From 9a0679fdacdad6a83f9f93858bd45a9fae8d7d56 Mon Sep 17 00:00:00 2001 From: Jamie Bate Date: Thu, 9 Nov 2023 10:56:13 +1300 Subject: [PATCH 001/413] [BACK-2728] Tandem pump settings updates (#680) * include boluses to pump settings --- data/types/settings/pump/bolus.go | 63 ++++++++++++++ data/types/settings/pump/bolus_test.go | 109 ++++++++++++++++++++++++- data/types/settings/pump/pump.go | 12 +++ data/types/settings/pump/pump_test.go | 46 +++++++++-- data/types/settings/pump/test/bolus.go | 34 +++++++- data/types/settings/pump/test/pump.go | 3 +- 6 files changed, 257 insertions(+), 10 deletions(-) diff --git a/data/types/settings/pump/bolus.go b/data/types/settings/pump/bolus.go index 344d7f0a03..629d5964fa 100644 --- a/data/types/settings/pump/bolus.go +++ b/data/types/settings/pump/bolus.go @@ -1,8 +1,11 @@ package pump import ( + "sort" + "github.com/tidepool-org/platform/data" "github.com/tidepool-org/platform/structure" + structureValidator "github.com/tidepool-org/platform/structure/validator" ) type Bolus struct { @@ -53,3 +56,63 @@ func (b *Bolus) Normalize(normalizer data.Normalizer) { b.Extended.Normalize(normalizer.WithReference("extended")) } } + +type BolusMap map[string]*Bolus + +func ParseBolusMap(parser structure.ObjectParser) *BolusMap { + if !parser.Exists() { + return nil + } + datum := NewBolusMap() + parser.Parse(datum) + return datum +} + +func NewBolusMap() *BolusMap { + return &BolusMap{} +} + +func (b *BolusMap) Parse(parser structure.ObjectParser) { + for _, reference := range parser.References() { + b.Set(reference, ParseBolus(parser.WithReferenceObjectParser(reference))) + } +} + +func (b *BolusMap) Normalize(normalizer data.Normalizer) { + for _, name := range b.sortedNames() { + if datum := b.Get(name); datum != nil { + datum.Normalize(normalizer.WithReference(name)) + } + } +} + +func (b *BolusMap) Validate(validator structure.Validator) { + for _, name := range b.sortedNames() { + datumValidator := validator.WithReference(name) + if datum := b.Get(name); datum != nil { + datum.Validate(datumValidator) + } else { + datumValidator.ReportError(structureValidator.ErrorValueNotExists()) + } + } +} + +func (b *BolusMap) Get(name string) *Bolus { + if datumArray, exists := (*b)[name]; exists { + return datumArray + } + return nil +} + +func (b *BolusMap) Set(name string, datum *Bolus) { + (*b)[name] = datum +} + +func (b *BolusMap) sortedNames() []string { + names := []string{} + for name := range *b { + names = append(names, name) + } + sort.Strings(names) + return names +} diff --git a/data/types/settings/pump/bolus_test.go b/data/types/settings/pump/bolus_test.go index 6452521ae6..54c715393d 100644 --- a/data/types/settings/pump/bolus_test.go +++ b/data/types/settings/pump/bolus_test.go @@ -33,7 +33,7 @@ var _ = Describe("Bolus", func() { Context("Validate", func() { DescribeTable("validates the datum", func(mutator func(datum *pump.Bolus), expectedErrors ...error) { - datum := pumpTest.NewBolus() + datum := pumpTest.NewRandomBolus() mutator(datum) dataTypesTest.ValidateWithExpectedOrigins(datum, structure.Origins(), expectedErrors...) }, @@ -75,7 +75,7 @@ var _ = Describe("Bolus", func() { DescribeTable("normalizes the datum", func(mutator func(datum *pump.Bolus)) { for _, origin := range structure.Origins() { - datum := pumpTest.NewBolus() + datum := pumpTest.NewRandomBolus() mutator(datum) expectedDatum := pumpTest.CloneBolus(datum) normalizer := dataNormalizer.New() @@ -98,4 +98,109 @@ var _ = Describe("Bolus", func() { ) }) }) + + Context("Boluses", func() { + + Context("Validate", func() { + DescribeTable("validates the datum", + func(mutator func(datum *pump.BolusMap), expectedErrors ...error) { + datum := pump.NewBolusMap() + mutator(datum) + dataTypesTest.ValidateWithExpectedOrigins(datum, structure.Origins(), expectedErrors...) + }, + Entry("succeeds", + func(datum *pump.BolusMap) {}, + ), + Entry("empty", + func(datum *pump.BolusMap) { + *datum = *pump.NewBolusMap() + }, + ), + + Entry("single invalid", + func(datum *pump.BolusMap) { + invalid := pumpTest.NewRandomBolus() + invalid.AmountMaximum.Units = nil + datum.Set("one", invalid) + }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/one/amountMaximum/units"), + ), + Entry("single valid", + func(datum *pump.BolusMap) { + datum.Set("one", pumpTest.NewRandomBolus()) + }, + ), + Entry("multiple valid", + func(datum *pump.BolusMap) { + datum.Set("one", pumpTest.NewRandomBolus()) + datum.Set("two", pumpTest.NewRandomBolus()) + datum.Set("three", pumpTest.NewRandomBolus()) + }, + ), + Entry("multiple errors", + func(datum *pump.BolusMap) { + invalid := pumpTest.NewRandomBolus() + invalid.AmountMaximum.Units = nil + + invalidThree := pumpTest.NewRandomBolus() + invalidThree.AmountMaximum.Value = nil + + datum.Set("one", invalid) + datum.Set("two", pumpTest.NewRandomBolus()) + datum.Set("three", invalidThree) + }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/one/amountMaximum/units"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/three/amountMaximum/value"), + ), + ) + }) + Context("Normalize", func() { + DescribeTable("normalizes the datum", + func(mutator func(datum *pump.BolusMap), expectator func(datum *pump.BolusMap, expectedDatum *pump.BolusMap)) { + for _, origin := range structure.Origins() { + datum := pumpTest.NewRandomBolusMap(1, 4) + mutator(datum) + expectedDatum := pumpTest.CloneBolusMap(datum) + normalizer := dataNormalizer.New() + Expect(normalizer).ToNot(BeNil()) + datum.Normalize(normalizer.WithOrigin(origin)) + Expect(normalizer.Error()).To(BeNil()) + Expect(normalizer.Data()).To(BeEmpty()) + if expectator != nil { + expectator(datum, expectedDatum) + } + Expect(datum).To(Equal(expectedDatum)) + } + }, + Entry("does not modify the datum", + func(datum *pump.BolusMap) {}, + nil, + ), + Entry("does not modify the datum; amountMaximum missing", + func(datum *pump.BolusMap) { + for name := range *datum { + (*(*datum)[name]).AmountMaximum = nil + } + }, + nil, + ), + Entry("does not modify the datum; calculator missing", + func(datum *pump.BolusMap) { + for name := range *datum { + (*(*datum)[name]).Calculator = nil + } + }, + nil, + ), + Entry("does not modify the datum; extended missing", + func(datum *pump.BolusMap) { + for name := range *datum { + (*(*datum)[name]).Extended = nil + } + }, + nil, + ), + ) + }) + }) }) diff --git a/data/types/settings/pump/pump.go b/data/types/settings/pump/pump.go index eb61abdfb0..f5e1396fab 100644 --- a/data/types/settings/pump/pump.go +++ b/data/types/settings/pump/pump.go @@ -42,6 +42,7 @@ type Pump struct { BloodGlucoseTargetSchedule *BloodGlucoseTargetStartArray `json:"bgTarget,omitempty" bson:"bgTarget,omitempty"` // TODO: Move into BolusCalculator struct; rename bloodGlucoseTarget BloodGlucoseTargetSchedules *BloodGlucoseTargetStartArrayMap `json:"bgTargets,omitempty" bson:"bgTargets,omitempty"` // TODO: Move into BolusCalculator struct; rename bloodGlucoseTargets Bolus *Bolus `json:"bolus,omitempty" bson:"bolus,omitempty"` + Boluses *BolusMap `json:"boluses,omitempty" bson:"boluses,omitempty"` CarbohydrateRatioSchedule *CarbohydrateRatioStartArray `json:"carbRatio,omitempty" bson:"carbRatio,omitempty"` // TODO: Move into BolusCalculator struct; rename carbohydrateRatio CarbohydrateRatioSchedules *CarbohydrateRatioStartArrayMap `json:"carbRatios,omitempty" bson:"carbRatios,omitempty"` // TODO: Move into BolusCalculator struct; rename carbohydrateRatios Display *Display `json:"display,omitempty" bson:"display,omitempty"` @@ -85,6 +86,7 @@ func (p *Pump) Parse(parser structure.ObjectParser) { p.BloodGlucoseTargetSchedule = ParseBloodGlucoseTargetStartArray(parser.WithReferenceArrayParser("bgTarget")) p.BloodGlucoseTargetSchedules = ParseBloodGlucoseTargetStartArrayMap(parser.WithReferenceObjectParser("bgTargets")) p.Bolus = ParseBolus(parser.WithReferenceObjectParser("bolus")) + p.Boluses = ParseBolusMap(parser.WithReferenceObjectParser("boluses")) p.CarbohydrateRatioSchedule = ParseCarbohydrateRatioStartArray(parser.WithReferenceArrayParser("carbRatio")) p.CarbohydrateRatioSchedules = ParseCarbohydrateRatioStartArrayMap(parser.WithReferenceObjectParser("carbRatios")) p.Display = ParseDisplay(parser.WithReferenceObjectParser("display")) @@ -147,9 +149,16 @@ func (p *Pump) Validate(validator structure.Validator) { } else if p.BloodGlucoseTargetSchedules != nil { p.BloodGlucoseTargetSchedules.Validate(validator.WithReference("bgTargets"), unitsBloodGlucose) } + if p.Bolus != nil { p.Bolus.Validate(validator.WithReference("bolus")) + if p.Boluses != nil { + validator.WithReference("boluses").ReportError(structureValidator.ErrorValueExists()) + } + } else if p.Boluses != nil { + p.Boluses.Validate(validator.WithReference("boluses")) } + if p.CarbohydrateRatioSchedule != nil { p.CarbohydrateRatioSchedule.Validate(validator.WithReference("carbRatio")) if p.CarbohydrateRatioSchedules != nil { @@ -232,6 +241,9 @@ func (p *Pump) Normalize(normalizer data.Normalizer) { if p.Bolus != nil { p.Bolus.Normalize(normalizer.WithReference("bolus")) } + if p.Boluses != nil { + p.Boluses.Normalize(normalizer.WithReference("boluses")) + } if p.CarbohydrateRatioSchedule != nil { p.CarbohydrateRatioSchedule.Normalize(normalizer.WithReference("carbRatio")) } diff --git a/data/types/settings/pump/pump_test.go b/data/types/settings/pump/pump_test.go index c0e80ef399..077a2b031b 100644 --- a/data/types/settings/pump/pump_test.go +++ b/data/types/settings/pump/pump_test.go @@ -1,6 +1,7 @@ package pump_test import ( + "fmt" "sort" . "github.com/onsi/ginkgo/v2" @@ -43,6 +44,7 @@ var _ = Describe("Pump", func() { Expect(datum.BloodGlucoseTargetSchedule).To(BeNil()) Expect(datum.BloodGlucoseTargetSchedules).To(BeNil()) Expect(datum.Bolus).To(BeNil()) + Expect(datum.Boluses).To(BeNil()) Expect(datum.CarbohydrateRatioSchedule).To(BeNil()) Expect(datum.CarbohydrateRatioSchedules).To(BeNil()) Expect(datum.Display).To(BeNil()) @@ -278,16 +280,49 @@ var _ = Describe("Pump", func() { ), Entry("bolus missing", pointer.FromString("mmol/L"), - func(datum *pump.Pump, unitsBloodGlucose *string) { datum.Bolus = nil }, + func(datum *pump.Pump, unitsBloodGlucose *string) { + datum.Bolus = nil + }, ), Entry("bolus invalid", pointer.FromString("mmol/L"), - func(datum *pump.Pump, unitsBloodGlucose *string) { datum.Bolus.Extended.Enabled = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/bolus/extended/enabled", pumpTest.NewMeta()), + func(datum *pump.Pump, unitsBloodGlucose *string) { + datum.Boluses = nil + datum.Bolus = pumpTest.NewRandomBolus() + datum.Bolus.Calculator.Enabled = nil + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/bolus/calculator/enabled", pumpTest.NewMeta()), ), Entry("bolus valid", pointer.FromString("mmol/L"), - func(datum *pump.Pump, unitsBloodGlucose *string) { datum.Bolus = pumpTest.NewBolus() }, + func(datum *pump.Pump, unitsBloodGlucose *string) { + datum.Boluses = nil + datum.Bolus = pumpTest.NewRandomBolus() + }, + ), + Entry("boluses missing", + pointer.FromString("mmol/L"), + func(datum *pump.Pump, unitsBloodGlucose *string) { datum.Boluses = nil }, + ), + Entry("boluses invalid", + pointer.FromString("mmol/L"), + func(datum *pump.Pump, unitsBloodGlucose *string) { + datum.Bolus = nil + datum.Boluses = pumpTest.NewRandomBolusMap(2, 2) + (*datum.Boluses)[pumpTest.BolusName(1)].AmountMaximum.Units = nil + (*datum.Boluses)[pumpTest.BolusName(2)].Extended.Enabled = nil + (*datum.Boluses)[pumpTest.BolusName(1)].Calculator.Enabled = nil + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), fmt.Sprintf("/boluses/%s/amountMaximum/units", pumpTest.BolusName(1)), pumpTest.NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), fmt.Sprintf("/boluses/%s/calculator/enabled", pumpTest.BolusName(1)), pumpTest.NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), fmt.Sprintf("/boluses/%s/extended/enabled", pumpTest.BolusName(2)), pumpTest.NewMeta()), + ), + Entry("boluses valid", + pointer.FromString("mmol/L"), + func(datum *pump.Pump, unitsBloodGlucose *string) { + datum.Bolus = nil + datum.Boluses = pumpTest.NewRandomBolusMap(1, 5) + }, ), Entry("carbohydrate ratio schedule and carbohydrate ratio schedules missing", pointer.FromString("mmol/L"), @@ -672,7 +707,8 @@ var _ = Describe("Pump", func() { datum.BloodGlucoseTargetSchedules = nil datum.BloodGlucoseTargetPhysicalActivity = dataBloodGlucose.NewTarget() datum.BloodGlucoseTargetPreprandial = dataBloodGlucose.NewTarget() - datum.BloodGlucoseTargetSchedules = nil + datum.Boluses = nil + datum.Bolus = pumpTest.NewRandomBolus() datum.Bolus.Extended.Enabled = nil invalidCarbohydrateRatioSchedule := pumpTest.NewCarbohydrateRatioStartArray() (*invalidCarbohydrateRatioSchedule)[0].Start = nil diff --git a/data/types/settings/pump/test/bolus.go b/data/types/settings/pump/test/bolus.go index 105d990b99..2a24e39ddb 100644 --- a/data/types/settings/pump/test/bolus.go +++ b/data/types/settings/pump/test/bolus.go @@ -1,11 +1,17 @@ package test -import "github.com/tidepool-org/platform/data/types/settings/pump" +import ( + "fmt" -func NewBolus() *pump.Bolus { + "github.com/tidepool-org/platform/data/types/settings/pump" + "github.com/tidepool-org/platform/test" +) + +func NewRandomBolus() *pump.Bolus { datum := pump.NewBolus() datum.AmountMaximum = NewBolusAmountMaximum() datum.Extended = NewBolusExtended() + datum.Calculator = NewBolusCalculator() return datum } @@ -16,5 +22,29 @@ func CloneBolus(datum *pump.Bolus) *pump.Bolus { clone := pump.NewBolus() clone.AmountMaximum = CloneBolusAmountMaximum(datum.AmountMaximum) clone.Extended = CloneBolusExtended(datum.Extended) + clone.Calculator = CloneBolusCalculator(datum.Calculator) + return clone +} + +func BolusName(index int) string { + return fmt.Sprintf("bolus-%d", index) +} + +func NewRandomBolusMap(minimumLength int, maximumLength int) *pump.BolusMap { + datum := pump.NewBolusMap() + for count := test.RandomIntFromRange(minimumLength, maximumLength); count > 0; count-- { + datum.Set(BolusName(count), NewRandomBolus()) + } + return datum +} + +func CloneBolusMap(datum *pump.BolusMap) *pump.BolusMap { + if datum == nil { + return nil + } + clone := pump.NewBolusMap() + for k, v := range *datum { + (*clone)[k] = CloneBolus(v) + } return clone } diff --git a/data/types/settings/pump/test/pump.go b/data/types/settings/pump/test/pump.go index 39992eae95..1f5314544d 100644 --- a/data/types/settings/pump/test/pump.go +++ b/data/types/settings/pump/test/pump.go @@ -48,7 +48,7 @@ func NewPump(unitsBloodGlucose *string) *pump.Pump { datum.BloodGlucoseTargetPreprandial = dataBloodGlucoseTest.RandomTarget(unitsBloodGlucose) datum.BloodGlucoseTargetSchedules = pump.NewBloodGlucoseTargetStartArrayMap() datum.BloodGlucoseTargetSchedules.Set(scheduleName, RandomBloodGlucoseTargetStartArray(unitsBloodGlucose)) - datum.Bolus = NewBolus() + datum.Boluses = NewRandomBolusMap(2, 4) datum.CarbohydrateRatioSchedules = pump.NewCarbohydrateRatioStartArrayMap() datum.CarbohydrateRatioSchedules.Set(scheduleName, NewCarbohydrateRatioStartArray()) datum.Display = NewDisplay() @@ -86,6 +86,7 @@ func ClonePump(datum *pump.Pump) *pump.Pump { clone.BloodGlucoseTargetSchedule = CloneBloodGlucoseTargetStartArray(datum.BloodGlucoseTargetSchedule) clone.BloodGlucoseTargetSchedules = CloneBloodGlucoseTargetStartArrayMap(datum.BloodGlucoseTargetSchedules) clone.Bolus = CloneBolus(datum.Bolus) + clone.Boluses = CloneBolusMap(datum.Boluses) clone.CarbohydrateRatioSchedule = CloneCarbohydrateRatioStartArray(datum.CarbohydrateRatioSchedule) clone.CarbohydrateRatioSchedules = CloneCarbohydrateRatioStartArrayMap(datum.CarbohydrateRatioSchedules) clone.Display = CloneDisplay(datum.Display) From b2242ed50e871ea36cad77594aaaacb45d74ee63 Mon Sep 17 00:00:00 2001 From: Jamie Bate Date: Thu, 9 Nov 2023 10:58:15 +1300 Subject: [PATCH 002/413] [BACK-2520] include pump sleep schedule (#678) * include pump sleep schedule * include SleepSchedules in pump settings * remove cruft --- data/types/common/common_suite_test.go | 11 + data/types/common/day.go | 57 +++++ data/types/common/day_test.go | 76 ++++++ data/types/settings/cgm/scheduled_alert.go | 23 +- .../settings/cgm/scheduled_alert_test.go | 40 +--- .../settings/cgm/test/scheduled_alert.go | 3 +- data/types/settings/pump/pump.go | 8 + data/types/settings/pump/pump_test.go | 30 +++ data/types/settings/pump/sleep_schedule.go | 109 +++++++++ .../settings/pump/sleep_schedule_test.go | 217 ++++++++++++++++++ .../settings/pump/test/sleep_schedule.go | 87 +++++++ dexcom/fetch/translate.go | 15 +- 12 files changed, 612 insertions(+), 64 deletions(-) create mode 100644 data/types/common/common_suite_test.go create mode 100644 data/types/common/day.go create mode 100644 data/types/common/day_test.go create mode 100644 data/types/settings/pump/sleep_schedule.go create mode 100644 data/types/settings/pump/sleep_schedule_test.go create mode 100644 data/types/settings/pump/test/sleep_schedule.go diff --git a/data/types/common/common_suite_test.go b/data/types/common/common_suite_test.go new file mode 100644 index 0000000000..5f35361ef7 --- /dev/null +++ b/data/types/common/common_suite_test.go @@ -0,0 +1,11 @@ +package common_test + +import ( + "testing" + + "github.com/tidepool-org/platform/test" +) + +func TestSuite(t *testing.T) { + test.Test(t) +} diff --git a/data/types/common/day.go b/data/types/common/day.go new file mode 100644 index 0000000000..186164d884 --- /dev/null +++ b/data/types/common/day.go @@ -0,0 +1,57 @@ +package common + +const ( + DaySunday = "sunday" + DayMonday = "monday" + DayTuesday = "tuesday" + DayWednesday = "wednesday" + DayThursday = "thursday" + DayFriday = "friday" + DaySaturday = "saturday" +) + +func DaysOfWeek() []string { + return []string{ + DaySunday, + DayMonday, + DayTuesday, + DayWednesday, + DayThursday, + DayFriday, + DaySaturday, + } +} + +type DaysOfWeekByDayIndex []string + +func (d DaysOfWeekByDayIndex) Len() int { + return len(d) +} +func (d DaysOfWeekByDayIndex) Swap(i int, j int) { + d[i], d[j] = d[j], d[i] +} + +func (d DaysOfWeekByDayIndex) Less(i int, j int) bool { + return DayIndex(d[i]) < DayIndex(d[j]) +} + +func DayIndex(day string) int { + switch day { + case DaySunday: + return 1 + case DayMonday: + return 2 + case DayTuesday: + return 3 + case DayWednesday: + return 4 + case DayThursday: + return 5 + case DayFriday: + return 6 + case DaySaturday: + return 7 + default: + return 0 + } +} diff --git a/data/types/common/day_test.go b/data/types/common/day_test.go new file mode 100644 index 0000000000..c12e1a9390 --- /dev/null +++ b/data/types/common/day_test.go @@ -0,0 +1,76 @@ +package common_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/tidepool-org/platform/data/types/common" +) + +var _ = Describe("Day", func() { + + It("DaySunday is expected", func() { + Expect(common.DaySunday).To(Equal("sunday")) + }) + + It("DayMonday is expected", func() { + Expect(common.DayMonday).To(Equal("monday")) + }) + + It("DayTuesday is expected", func() { + Expect(common.DayTuesday).To(Equal("tuesday")) + }) + + It("DayWednesday is expected", func() { + Expect(common.DayWednesday).To(Equal("wednesday")) + }) + + It("DayThursday is expected", func() { + Expect(common.DayThursday).To(Equal("thursday")) + }) + + It("DayFriday is expected", func() { + Expect(common.DayFriday).To(Equal("friday")) + }) + + It("DaySaturday is expected", func() { + Expect(common.DaySaturday).To(Equal("saturday")) + }) + + It("DaysOfWeek returns expected", func() { + Expect(common.DaysOfWeek()).To(Equal([]string{"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"})) + Expect(common.DaysOfWeek()).To(Equal([]string{ + common.DaySunday, + common.DayMonday, + common.DayTuesday, + common.DayWednesday, + common.DayThursday, + common.DayFriday, + common.DaySaturday, + })) + }) + + Context("DayIndex", func() { + DescribeTable("return the expected index when the day", + func(day string, expectedIndex int) { + Expect(common.DayIndex(day)).To(Equal(expectedIndex)) + }, + Entry("is an empty string", "", 0), + Entry("is sunday", "sunday", 1), + Entry("is constant sunday", common.DaySunday, 1), + Entry("is monday", "monday", 2), + Entry("is constant monday", common.DayMonday, 2), + Entry("is tuesday", "tuesday", 3), + Entry("is constant tuesday", common.DayTuesday, 3), + Entry("is wednesday", "wednesday", 4), + Entry("isconstant wednesday", common.DayWednesday, 4), + Entry("is thursday", "thursday", 5), + Entry("is constant thursday", common.DayThursday, 5), + Entry("is friday", "friday", 6), + Entry("is constant friday", common.DayFriday, 6), + Entry("is saturday", "saturday", 7), + Entry("is constant saturday", common.DaySaturday, 7), + Entry("is an invalid string", "invalid", 0), + ) + }) +}) diff --git a/data/types/settings/cgm/scheduled_alert.go b/data/types/settings/cgm/scheduled_alert.go index 34178c7d16..9a447aff38 100644 --- a/data/types/settings/cgm/scheduled_alert.go +++ b/data/types/settings/cgm/scheduled_alert.go @@ -3,6 +3,7 @@ package cgm import ( "strconv" + "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/structure" structureValidator "github.com/tidepool-org/platform/structure/validator" ) @@ -12,14 +13,6 @@ const ( ScheduledAlertNameLengthMaximum = 100 - ScheduledAlertDaysSunday = "sunday" - ScheduledAlertDaysMonday = "monday" - ScheduledAlertDaysTuesday = "tuesday" - ScheduledAlertDaysWednesday = "wednesday" - ScheduledAlertDaysThursday = "thursday" - ScheduledAlertDaysFriday = "friday" - ScheduledAlertDaysSaturday = "saturday" - ScheduledAlertStartMaximum = 86400000 ScheduledAlertStartMinimum = 0 @@ -27,18 +20,6 @@ const ( ScheduledAlertEndMinimum = 0 ) -func ScheduledAlertDays() []string { - return []string{ - ScheduledAlertDaysSunday, - ScheduledAlertDaysMonday, - ScheduledAlertDaysTuesday, - ScheduledAlertDaysWednesday, - ScheduledAlertDaysThursday, - ScheduledAlertDaysFriday, - ScheduledAlertDaysSaturday, - } -} - type ScheduledAlerts []*ScheduledAlert func ParseScheduledAlerts(parser structure.ArrayParser) *ScheduledAlerts { @@ -107,7 +88,7 @@ func (s *ScheduledAlert) Parse(parser structure.ObjectParser) { func (s *ScheduledAlert) Validate(validator structure.Validator) { validator.String("name", s.Name).NotEmpty().LengthLessThanOrEqualTo(ScheduledAlertNameLengthMaximum) - validator.StringArray("days", s.Days).Exists().EachOneOf(ScheduledAlertDays()...).EachUnique() + validator.StringArray("days", s.Days).Exists().EachOneOf(common.DaysOfWeek()...).EachUnique() validator.Int("start", s.Start).Exists().InRange(ScheduledAlertStartMinimum, ScheduledAlertStartMaximum) validator.Int("end", s.End).Exists().InRange(ScheduledAlertEndMinimum, ScheduledAlertEndMaximum) if alertsValidator := validator.WithReference("alerts"); s.Alerts != nil { diff --git a/data/types/settings/cgm/scheduled_alert_test.go b/data/types/settings/cgm/scheduled_alert_test.go index 606c6975e9..99da23ed7e 100644 --- a/data/types/settings/cgm/scheduled_alert_test.go +++ b/data/types/settings/cgm/scheduled_alert_test.go @@ -5,6 +5,8 @@ import ( . "github.com/onsi/gomega" dataTypesSettingsCgm "github.com/tidepool-org/platform/data/types/settings/cgm" + + dataTypesCommon "github.com/tidepool-org/platform/data/types/common" dataTypesSettingsCgmTest "github.com/tidepool-org/platform/data/types/settings/cgm/test" errorsTest "github.com/tidepool-org/platform/errors/test" "github.com/tidepool-org/platform/pointer" @@ -21,34 +23,6 @@ var _ = Describe("ScheduledAlert", func() { Expect(dataTypesSettingsCgm.ScheduledAlertNameLengthMaximum).To(Equal(100)) }) - It("ScheduledAlertDaysSunday is expected", func() { - Expect(dataTypesSettingsCgm.ScheduledAlertDaysSunday).To(Equal("sunday")) - }) - - It("ScheduledAlertDaysMonday is expected", func() { - Expect(dataTypesSettingsCgm.ScheduledAlertDaysMonday).To(Equal("monday")) - }) - - It("ScheduledAlertDaysTuesday is expected", func() { - Expect(dataTypesSettingsCgm.ScheduledAlertDaysTuesday).To(Equal("tuesday")) - }) - - It("ScheduledAlertDaysWednesday is expected", func() { - Expect(dataTypesSettingsCgm.ScheduledAlertDaysWednesday).To(Equal("wednesday")) - }) - - It("ScheduledAlertDaysThursday is expected", func() { - Expect(dataTypesSettingsCgm.ScheduledAlertDaysThursday).To(Equal("thursday")) - }) - - It("ScheduledAlertDaysFriday is expected", func() { - Expect(dataTypesSettingsCgm.ScheduledAlertDaysFriday).To(Equal("friday")) - }) - - It("ScheduledAlertDaysSaturday is expected", func() { - Expect(dataTypesSettingsCgm.ScheduledAlertDaysSaturday).To(Equal("saturday")) - }) - It("ScheduledAlertStartMaximum is expected", func() { Expect(dataTypesSettingsCgm.ScheduledAlertStartMaximum).To(Equal(86400000)) }) @@ -65,10 +39,6 @@ var _ = Describe("ScheduledAlert", func() { Expect(dataTypesSettingsCgm.ScheduledAlertEndMinimum).To(Equal(0)) }) - It("ScheduledAlertDays returns expected", func() { - Expect(dataTypesSettingsCgm.ScheduledAlertDays()).To(Equal([]string{"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"})) - }) - Context("ParseScheduledAlerts", func() { // TODO }) @@ -204,20 +174,20 @@ var _ = Describe("ScheduledAlert", func() { ), Entry("days contains invalid", func(datum *dataTypesSettingsCgm.ScheduledAlert) { - datum.Days = pointer.FromStringArray(append([]string{"invalid"}, test.RandomStringArrayFromRangeAndArrayWithoutDuplicates(0, len(dataTypesSettingsCgm.ScheduledAlertDays())-1, dataTypesSettingsCgm.ScheduledAlertDays())...)) + datum.Days = pointer.FromStringArray(append([]string{"invalid"}, test.RandomStringArrayFromRangeAndArrayWithoutDuplicates(0, len(dataTypesCommon.DaysOfWeek())-1, dataTypesCommon.DaysOfWeek())...)) }, errorsTest.WithPointerSource(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"}), "/days/0"), ), Entry("days contains duplicate", func(datum *dataTypesSettingsCgm.ScheduledAlert) { - duplicate := test.RandomStringFromArray(dataTypesSettingsCgm.ScheduledAlertDays()) + duplicate := test.RandomStringFromArray(dataTypesCommon.DaysOfWeek()) datum.Days = pointer.FromStringArray([]string{duplicate, duplicate}) }, errorsTest.WithPointerSource(structureValidator.ErrorValueDuplicate(), "/days/1"), ), Entry("days valid", func(datum *dataTypesSettingsCgm.ScheduledAlert) { - datum.Days = pointer.FromStringArray(test.RandomStringArrayFromRangeAndArrayWithoutDuplicates(1, len(dataTypesSettingsCgm.ScheduledAlertDays()), dataTypesSettingsCgm.ScheduledAlertDays())) + datum.Days = pointer.FromStringArray(test.RandomStringArrayFromRangeAndArrayWithoutDuplicates(1, len(dataTypesCommon.DaysOfWeek()), dataTypesCommon.DaysOfWeek())) }, ), Entry("start missing", diff --git a/data/types/settings/cgm/test/scheduled_alert.go b/data/types/settings/cgm/test/scheduled_alert.go index 2ba30b0368..11c3c255d7 100644 --- a/data/types/settings/cgm/test/scheduled_alert.go +++ b/data/types/settings/cgm/test/scheduled_alert.go @@ -1,6 +1,7 @@ package test import ( + "github.com/tidepool-org/platform/data/types/common" dataTypesSettingsCgm "github.com/tidepool-org/platform/data/types/settings/cgm" "github.com/tidepool-org/platform/pointer" "github.com/tidepool-org/platform/test" @@ -39,7 +40,7 @@ func NewArrayFromScheduledAlerts(datum *dataTypesSettingsCgm.ScheduledAlerts, ob func RandomScheduledAlert() *dataTypesSettingsCgm.ScheduledAlert { datum := dataTypesSettingsCgm.NewScheduledAlert() datum.Name = pointer.FromString(test.RandomStringFromRange(1, dataTypesSettingsCgm.ScheduledAlertNameLengthMaximum)) - datum.Days = pointer.FromStringArray(test.RandomStringArrayFromRangeAndArrayWithoutDuplicates(1, len(dataTypesSettingsCgm.ScheduledAlertDays()), dataTypesSettingsCgm.ScheduledAlertDays())) + datum.Days = pointer.FromStringArray(test.RandomStringArrayFromRangeAndArrayWithoutDuplicates(1, len(common.DaysOfWeek()), common.DaysOfWeek())) datum.Start = pointer.FromInt(test.RandomIntFromRange(dataTypesSettingsCgm.ScheduledAlertStartMinimum, dataTypesSettingsCgm.ScheduledAlertStartMaximum)) datum.End = pointer.FromInt(test.RandomIntFromRange(dataTypesSettingsCgm.ScheduledAlertEndMinimum, dataTypesSettingsCgm.ScheduledAlertEndMaximum)) datum.Alerts = RandomAlerts() diff --git a/data/types/settings/pump/pump.go b/data/types/settings/pump/pump.go index f5e1396fab..9afccb8dfe 100644 --- a/data/types/settings/pump/pump.go +++ b/data/types/settings/pump/pump.go @@ -58,6 +58,7 @@ type Pump struct { OverridePresets *OverridePresetMap `json:"overridePresets,omitempty" bson:"overridePresets,omitempty"` ScheduleTimeZoneOffset *int `json:"scheduleTimeZoneOffset,omitempty" bson:"scheduleTimeZoneOffset,omitempty"` SerialNumber *string `json:"serialNumber,omitempty" bson:"serialNumber,omitempty"` + SleepSchedules *SleepScheduleMap `json:"sleepSchedules,omitempty" bson:"sleepSchedules,omitempty"` SoftwareVersion *string `json:"softwareVersion,omitempty" bson:"softwareVersion,omitempty"` Units *Units `json:"units,omitempty" bson:"units,omitempty"` // TODO: Move into appropriate structs } @@ -101,6 +102,7 @@ func (p *Pump) Parse(parser structure.ObjectParser) { p.Name = parser.String("name") p.OverridePresets = ParseOverridePresetMap(parser.WithReferenceObjectParser("overridePresets")) p.ScheduleTimeZoneOffset = parser.Int("scheduleTimeZoneOffset") + p.SleepSchedules = ParseSleepScheduleMap(parser.WithReferenceObjectParser("sleepSchedules")) p.SerialNumber = parser.String("serialNumber") p.SoftwareVersion = parser.String("softwareVersion") p.Units = ParseUnits(parser.WithReferenceObjectParser("units")) @@ -194,6 +196,9 @@ func (p *Pump) Validate(validator structure.Validator) { if p.OverridePresets != nil { p.OverridePresets.Validate(validator.WithReference("overridePresets"), unitsBloodGlucose) } + if p.SleepSchedules != nil { + p.SleepSchedules.Validate(validator.WithReference("sleepSchedules")) + } validator.Int("scheduleTimeZoneOffset", p.ScheduleTimeZoneOffset).InRange(ScheduleTimeZoneOffsetMinimum, ScheduleTimeZoneOffsetMaximum) validator.String("serialNumber", p.SerialNumber).NotEmpty().LengthLessThanOrEqualTo(SerialNumberLengthMaximum) validator.String("softwareVersion", p.SoftwareVersion).NotEmpty().LengthLessThanOrEqualTo(SoftwareVersionLengthMaximum) @@ -270,6 +275,9 @@ func (p *Pump) Normalize(normalizer data.Normalizer) { if p.OverridePresets != nil { p.OverridePresets.Normalize(normalizer.WithReference("overridePresets"), unitsBloodGlucose) } + if p.SleepSchedules != nil { + p.SleepSchedules.Normalize(normalizer.WithReference("sleepSchedules")) + } if p.Units != nil { p.Units.Normalize(normalizer.WithReference("units")) } diff --git a/data/types/settings/pump/pump_test.go b/data/types/settings/pump/pump_test.go index 077a2b031b..64a65fd75f 100644 --- a/data/types/settings/pump/pump_test.go +++ b/data/types/settings/pump/pump_test.go @@ -59,6 +59,7 @@ var _ = Describe("Pump", func() { Expect(datum.Name).To(BeNil()) Expect(datum.OverridePresets).To(BeNil()) Expect(datum.ScheduleTimeZoneOffset).To(BeNil()) + Expect(datum.SleepSchedules).To(BeNil()) Expect(datum.SerialNumber).To(BeNil()) Expect(datum.SoftwareVersion).To(BeNil()) Expect(datum.Units).To(BeNil()) @@ -652,6 +653,35 @@ var _ = Describe("Pump", func() { }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorLengthNotLessThanOrEqualTo(101, 100), "/serialNumber", pumpTest.NewMeta()), ), + Entry("sleep schedules missing", + pointer.FromString("mmol/L"), + func(datum *pump.Pump, unitsBloodGlucose *string) { + datum.SleepSchedules = nil + }, + ), + Entry("sleep schedules empty", + pointer.FromString("mmol/L"), + func(datum *pump.Pump, unitsBloodGlucose *string) { + datum.SleepSchedules = pump.NewSleepScheduleMap() + }, + ), + Entry("sleep schedules valid", + pointer.FromString("mmol/L"), + func(datum *pump.Pump, unitsBloodGlucose *string) { + datum.SleepSchedules = pumpTest.RandomSleepSchedules(3) + }, + ), + Entry("sleep schedules invalid", + pointer.FromString("mmol/L"), + func(datum *pump.Pump, unitsBloodGlucose *string) { + datum.SleepSchedules = pumpTest.RandomSleepSchedules(2) + (*datum.SleepSchedules)[pumpTest.SleepScheduleName(0)].End = pointer.FromInt(pump.SleepSchedulesMidnightOffsetMaximum + 1) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange( + pump.SleepSchedulesMidnightOffsetMaximum+1, 0, + pump.SleepSchedulesMidnightOffsetMaximum), + fmt.Sprintf("/sleepSchedules/%s/end", pumpTest.SleepScheduleName(0)), pumpTest.NewMeta()), + ), Entry("software version missing", pointer.FromString("mmol/L"), func(datum *pump.Pump, units *string) { datum.SoftwareVersion = nil }, diff --git a/data/types/settings/pump/sleep_schedule.go b/data/types/settings/pump/sleep_schedule.go new file mode 100644 index 0000000000..0da251b14c --- /dev/null +++ b/data/types/settings/pump/sleep_schedule.go @@ -0,0 +1,109 @@ +package pump + +import ( + "sort" + + "github.com/tidepool-org/platform/data" + "github.com/tidepool-org/platform/data/types/common" + "github.com/tidepool-org/platform/structure" + structureValidator "github.com/tidepool-org/platform/structure/validator" +) + +const ( + SleepSchedulesMidnightOffsetMaximum = 86400 + SleepSchedulesMidnightOffsetMinimum = 0 +) + +type SleepScheduleMap map[string]*SleepSchedule + +func ParseSleepScheduleMap(parser structure.ObjectParser) *SleepScheduleMap { + if !parser.Exists() { + return nil + } + datum := NewSleepScheduleMap() + parser.Parse(datum) + return datum +} + +func NewSleepScheduleMap() *SleepScheduleMap { + return &SleepScheduleMap{} +} + +func (s *SleepScheduleMap) Parse(parser structure.ObjectParser) { + for _, reference := range parser.References() { + s.Set(reference, ParseSleepSchedule(parser.WithReferenceObjectParser(reference))) + } +} + +func (s *SleepScheduleMap) Validate(validator structure.Validator) { + for _, name := range s.sortedNames() { + datumValidator := validator.WithReference(name) + if datum := s.Get(name); datum != nil { + datum.Validate(datumValidator) + } else { + datumValidator.ReportError(structureValidator.ErrorValueNotExists()) + } + } +} + +func (s *SleepScheduleMap) Normalize(normalizer data.Normalizer) {} + +func (s *SleepScheduleMap) Get(name string) *SleepSchedule { + if datum, exists := (*s)[name]; exists { + return datum + } + return nil +} + +func (s *SleepScheduleMap) Set(name string, datum *SleepSchedule) { + (*s)[name] = datum +} + +func (s *SleepScheduleMap) sortedNames() []string { + names := []string{} + for name := range *s { + names = append(names, name) + } + sort.Strings(names) + return names +} + +type SleepSchedule struct { + Enabled *bool `json:"enabled,omitempty" bson:"enabled,omitempty"` + Days *[]string `json:"days,omitempty" bson:"days,omitempty"` + Start *int `json:"start,omitempty" bson:"start,omitempty"` + End *int `json:"end,omitempty" bson:"end,omitempty"` +} + +func ParseSleepSchedule(parser structure.ObjectParser) *SleepSchedule { + if !parser.Exists() { + return nil + } + datum := NewSleepSchedule() + parser.Parse(datum) + return datum +} + +func NewSleepSchedule() *SleepSchedule { + return &SleepSchedule{} +} + +func (s *SleepSchedule) Parse(parser structure.ObjectParser) { + s.Enabled = parser.Bool("enabled") + s.Days = parser.StringArray("days") + s.Start = parser.Int("start") + s.End = parser.Int("end") +} + +func (s *SleepSchedule) Validate(validator structure.Validator) { + validator.Bool("enabled", s.Enabled).Exists() + if s.Enabled != nil { + if *s.Enabled { + validator.StringArray("days", s.Days).Exists().EachOneOf(common.DaysOfWeek()...).EachUnique() + validator.Int("start", s.Start).Exists().InRange(SleepSchedulesMidnightOffsetMinimum, SleepSchedulesMidnightOffsetMaximum) + validator.Int("end", s.End).Exists().InRange(SleepSchedulesMidnightOffsetMinimum, SleepSchedulesMidnightOffsetMaximum) + } + } +} + +func (s *SleepSchedule) Normalize(normalizer data.Normalizer) {} diff --git a/data/types/settings/pump/sleep_schedule_test.go b/data/types/settings/pump/sleep_schedule_test.go new file mode 100644 index 0000000000..3c0f2d7b39 --- /dev/null +++ b/data/types/settings/pump/sleep_schedule_test.go @@ -0,0 +1,217 @@ +package pump_test + +import ( + "fmt" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + dataTypesCommon "github.com/tidepool-org/platform/data/types/common" + dataTypesSettingsPump "github.com/tidepool-org/platform/data/types/settings/pump" + dataTypesSettingsPumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" + errorsTest "github.com/tidepool-org/platform/errors/test" + "github.com/tidepool-org/platform/pointer" + structureValidator "github.com/tidepool-org/platform/structure/validator" + "github.com/tidepool-org/platform/test" +) + +var _ = Describe("SleepSchedule", func() { + + Context("NewSleepSchedules", func() { + It("returns successfully with default values", func() { + datum := dataTypesSettingsPump.NewSleepScheduleMap() + Expect(datum).ToNot(BeNil()) + Expect(*datum).To(BeEmpty()) + }) + }) + + Context("SleepSchedules", func() { + + Context("Validate", func() { + DescribeTable("validates the datum", + func(mutator func(datum *dataTypesSettingsPump.SleepScheduleMap), expectedErrors ...error) { + datum := dataTypesSettingsPumpTest.RandomSleepSchedules(3) + mutator(datum) + errorsTest.ExpectEqual(structureValidator.New().Validate(datum), expectedErrors...) + }, + Entry("succeeds", + func(datum *dataTypesSettingsPump.SleepScheduleMap) {}, + ), + Entry("empty", + func(datum *dataTypesSettingsPump.SleepScheduleMap) { + *datum = *dataTypesSettingsPump.NewSleepScheduleMap() + }, + ), + Entry("has one", + func(datum *dataTypesSettingsPump.SleepScheduleMap) { + *datum = *dataTypesSettingsPumpTest.RandomSleepSchedules(1) + }, + ), + Entry("has many", + func(datum *dataTypesSettingsPump.SleepScheduleMap) { + *datum = *dataTypesSettingsPumpTest.RandomSleepSchedules(19) + }, + ), + Entry("entry missing", + func(datum *dataTypesSettingsPump.SleepScheduleMap) { + (*datum)[dataTypesSettingsPumpTest.SleepScheduleName(0)] = nil + }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), fmt.Sprintf("/%s", dataTypesSettingsPumpTest.SleepScheduleName(0))), + ), + Entry("multiple errors", + func(datum *dataTypesSettingsPump.SleepScheduleMap) { + *datum = *dataTypesSettingsPumpTest.RandomSleepSchedules(3) + (*datum)[dataTypesSettingsPumpTest.SleepScheduleName(1)] = nil + }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), fmt.Sprintf("/%s", dataTypesSettingsPumpTest.SleepScheduleName(1))), + ), + ) + }) + }) + + Context("NewSleepSchedule", func() { + It("returns successfully with default values", func() { + datum := dataTypesSettingsPump.NewSleepSchedule() + Expect(datum).ToNot(BeNil()) + Expect(datum.Enabled).To(BeNil()) + Expect(datum.Days).To(BeNil()) + Expect(datum.Start).To(BeNil()) + Expect(datum.End).To(BeNil()) + }) + }) + + Context("SleepSchedule", func() { + DescribeTable("serializes the datum as expected", + func(mutator func(datum *dataTypesSettingsPump.SleepSchedule)) { + datum := dataTypesSettingsPumpTest.RandomSleepSchedule() + mutator(datum) + test.ExpectSerializedObjectBSON(datum, dataTypesSettingsPumpTest.NewObjectFromSleepSchedule(datum, test.ObjectFormatBSON)) + test.ExpectSerializedObjectJSON(datum, dataTypesSettingsPumpTest.NewObjectFromSleepSchedule(datum, test.ObjectFormatJSON)) + }, + Entry("succeeds", + func(datum *dataTypesSettingsPump.SleepSchedule) {}, + ), + Entry("empty", + func(datum *dataTypesSettingsPump.SleepSchedule) { *datum = dataTypesSettingsPump.SleepSchedule{} }, + ), + ) + + Context("Validate", func() { + DescribeTable("validates the datum", + func(mutator func(datum *dataTypesSettingsPump.SleepSchedule), expectedErrors ...error) { + datum := dataTypesSettingsPumpTest.RandomSleepSchedule() + mutator(datum) + errorsTest.ExpectEqual(structureValidator.New().Validate(datum), expectedErrors...) + }, + Entry("succeeds", + func(datum *dataTypesSettingsPump.SleepSchedule) {}, + ), + Entry("enabled empty", + func(datum *dataTypesSettingsPump.SleepSchedule) { datum.Enabled = nil }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/enabled"), + ), + + Entry("days missing", + func(datum *dataTypesSettingsPump.SleepSchedule) { + datum.Days = nil + }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/days"), + ), + Entry("days contains invalid", + func(datum *dataTypesSettingsPump.SleepSchedule) { + datum.Days = pointer.FromStringArray(append([]string{"invalid"}, test.RandomStringArrayFromRangeAndArrayWithoutDuplicates(0, len(dataTypesCommon.DaysOfWeek())-1, dataTypesCommon.DaysOfWeek())...)) + }, + errorsTest.WithPointerSource(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"}), "/days/0"), + ), + Entry("days contains duplicate", + func(datum *dataTypesSettingsPump.SleepSchedule) { + duplicate := test.RandomStringFromArray(dataTypesCommon.DaysOfWeek()) + datum.Days = pointer.FromStringArray([]string{duplicate, duplicate}) + }, + errorsTest.WithPointerSource(structureValidator.ErrorValueDuplicate(), "/days/1"), + ), + Entry("days valid", + func(datum *dataTypesSettingsPump.SleepSchedule) { + datum.Days = pointer.FromStringArray(test.RandomStringArrayFromRangeAndArrayWithoutDuplicates(1, len(dataTypesCommon.DaysOfWeek()), dataTypesCommon.DaysOfWeek())) + }, + ), + Entry("start missing", + func(datum *dataTypesSettingsPump.SleepSchedule) { + datum.Start = nil + }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/start"), + ), + Entry("start out of range (lower)", + func(datum *dataTypesSettingsPump.SleepSchedule) { + datum.Start = pointer.FromInt(-1) + }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-1, + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum, + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum), "/start"), + ), + Entry("start in range (lower)", + func(datum *dataTypesSettingsPump.SleepSchedule) { + datum.Start = pointer.FromInt(dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum) + }, + ), + Entry("start in range (upper)", + func(datum *dataTypesSettingsPump.SleepSchedule) { + datum.Start = pointer.FromInt(dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum) + }, + ), + Entry("start out of range (upper)", + func(datum *dataTypesSettingsPump.SleepSchedule) { + datum.Start = pointer.FromInt(dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum + 1) + }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange( + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum+1, + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum, + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum), "/start"), + ), + Entry("end missing", + func(datum *dataTypesSettingsPump.SleepSchedule) { + datum.End = nil + }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/end"), + ), + Entry("end out of range (lower)", + func(datum *dataTypesSettingsPump.SleepSchedule) { + datum.End = pointer.FromInt(-1) + }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-1, + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum, + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum), "/end"), + ), + Entry("end in range (lower)", + func(datum *dataTypesSettingsPump.SleepSchedule) { + datum.End = pointer.FromInt(dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum) + }, + ), + Entry("end in range (upper)", + func(datum *dataTypesSettingsPump.SleepSchedule) { + datum.End = pointer.FromInt(dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum) + }, + ), + Entry("end out of range (upper)", + func(datum *dataTypesSettingsPump.SleepSchedule) { + datum.End = pointer.FromInt(dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum + 1) + }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange( + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum+1, + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum, + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum), "/end"), + ), + Entry("multiple errors", + func(datum *dataTypesSettingsPump.SleepSchedule) { + datum.Days = nil + datum.Start = nil + datum.End = nil + }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/days"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/start"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/end"), + ), + ) + }) + }) +}) diff --git a/data/types/settings/pump/test/sleep_schedule.go b/data/types/settings/pump/test/sleep_schedule.go new file mode 100644 index 0000000000..bc8c547993 --- /dev/null +++ b/data/types/settings/pump/test/sleep_schedule.go @@ -0,0 +1,87 @@ +package test + +import ( + "fmt" + + dataTypesCommon "github.com/tidepool-org/platform/data/types/common" + dataTypesSettingsPump "github.com/tidepool-org/platform/data/types/settings/pump" + "github.com/tidepool-org/platform/pointer" + "github.com/tidepool-org/platform/test" +) + +func SleepScheduleName(index int) string { + return fmt.Sprintf("schedule-%d", index) +} + +func RandomSleepSchedules(count int) *dataTypesSettingsPump.SleepScheduleMap { + datum := dataTypesSettingsPump.NewSleepScheduleMap() + for i := 0; i < count; i++ { + (*datum)[SleepScheduleName(i)] = RandomSleepSchedule() + } + return datum +} + +func CloneSleepSchedules(datum *dataTypesSettingsPump.SleepScheduleMap) *dataTypesSettingsPump.SleepScheduleMap { + if datum == nil { + return nil + } + clone := make(dataTypesSettingsPump.SleepScheduleMap, len(*datum)) + for index, d := range *datum { + clone[index] = CloneSleepSchedule(d) + } + return &clone +} + +func NewArrayFromSleepSchedules(datum *dataTypesSettingsPump.SleepScheduleMap, objectFormat test.ObjectFormat) []interface{} { + if datum == nil { + return nil + } + array := []interface{}{} + for _, d := range *datum { + array = append(array, NewObjectFromSleepSchedule(d, objectFormat)) + } + return array +} + +func RandomSleepSchedule() *dataTypesSettingsPump.SleepSchedule { + datum := dataTypesSettingsPump.NewSleepSchedule() + // enabled by default, if not enabled days, start and end not required + datum.Enabled = pointer.FromBool(true) + datum.Days = pointer.FromStringArray(test.RandomStringArrayFromRangeAndArrayWithoutDuplicates(1, len(dataTypesCommon.DaysOfWeek()), dataTypesCommon.DaysOfWeek())) + datum.Start = pointer.FromInt(test.RandomIntFromRange(dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum, dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum)) + datum.End = pointer.FromInt(test.RandomIntFromRange(dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum, dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum)) + return datum +} + +func CloneSleepSchedule(datum *dataTypesSettingsPump.SleepSchedule) *dataTypesSettingsPump.SleepSchedule { + if datum == nil { + return nil + } + clone := dataTypesSettingsPump.NewSleepSchedule() + clone.Enabled = pointer.CloneBool(datum.Enabled) + clone.Days = pointer.CloneStringArray(datum.Days) + clone.Start = pointer.CloneInt(datum.Start) + clone.End = pointer.CloneInt(datum.End) + return clone +} + +func NewObjectFromSleepSchedule(datum *dataTypesSettingsPump.SleepSchedule, objectFormat test.ObjectFormat) map[string]interface{} { + if datum == nil { + return nil + } + object := map[string]interface{}{} + if datum.Enabled != nil { + object["enabled"] = test.NewObjectFromBool(*datum.Enabled, objectFormat) + } + if datum.Days != nil { + object["days"] = test.NewObjectFromStringArray(*datum.Days, objectFormat) + } + if datum.Start != nil { + object["start"] = test.NewObjectFromInt(*datum.Start, objectFormat) + } + if datum.End != nil { + object["end"] = test.NewObjectFromInt(*datum.End, objectFormat) + } + + return object +} diff --git a/dexcom/fetch/translate.go b/dexcom/fetch/translate.go index d2f4033829..3f4fbaf6de 100644 --- a/dexcom/fetch/translate.go +++ b/dexcom/fetch/translate.go @@ -8,6 +8,7 @@ import ( dataBloodGlucose "github.com/tidepool-org/platform/data/blood/glucose" dataTypes "github.com/tidepool-org/platform/data/types" dataTypesActivityPhysical "github.com/tidepool-org/platform/data/types/activity/physical" + "github.com/tidepool-org/platform/data/types/common" dataTypesAlert "github.com/tidepool-org/platform/data/types/alert" dataTypesBloodGlucoseContinuous "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" @@ -205,19 +206,19 @@ func translateAlertScheduleSettingsDaysOfWeekToScheduledAlertDays(daysOfWeek *[] func translateAlertScheduleSettingsDayOfWeekToScheduledAlertDay(dayOfWeek string) string { switch dayOfWeek { case dexcom.AlertScheduleSettingsDaySunday: - return dataTypesSettingsCgm.ScheduledAlertDaysSunday + return common.DaySunday case dexcom.AlertScheduleSettingsDayMonday: - return dataTypesSettingsCgm.ScheduledAlertDaysMonday + return common.DayMonday case dexcom.AlertScheduleSettingsDayTuesday: - return dataTypesSettingsCgm.ScheduledAlertDaysTuesday + return common.DayTuesday case dexcom.AlertScheduleSettingsDayWednesday: - return dataTypesSettingsCgm.ScheduledAlertDaysWednesday + return common.DayWednesday case dexcom.AlertScheduleSettingsDayThursday: - return dataTypesSettingsCgm.ScheduledAlertDaysThursday + return common.DayThursday case dexcom.AlertScheduleSettingsDayFriday: - return dataTypesSettingsCgm.ScheduledAlertDaysFriday + return common.DayFriday case dexcom.AlertScheduleSettingsDaySaturday: - return dataTypesSettingsCgm.ScheduledAlertDaysSaturday + return common.DaySaturday } return "" } From e8e07ffdec3baaae0e4c9a9716b22bb7bd7bfea0 Mon Sep 17 00:00:00 2001 From: Jamie Bate Date: Thu, 9 Nov 2023 11:00:01 +1300 Subject: [PATCH 003/413] [back-37] jellyfish data migration (#665) * migrate existing jellyfish records * migrate jellyfish pumpSettings bolus if present --- migrations/back_37/back_37.go | 279 +++++++++++++++++++++++++++++ migrations/back_37/back_37_test.go | 110 ++++++++++++ 2 files changed, 389 insertions(+) create mode 100644 migrations/back_37/back_37.go create mode 100644 migrations/back_37/back_37_test.go diff --git a/migrations/back_37/back_37.go b/migrations/back_37/back_37.go new file mode 100644 index 0000000000..cc65cc1283 --- /dev/null +++ b/migrations/back_37/back_37.go @@ -0,0 +1,279 @@ +package main + +import ( + "context" + "fmt" + "strconv" + "time" + + "github.com/urfave/cli" + "go.mongodb.org/mongo-driver/bson" + + "github.com/tidepool-org/platform/application" + "github.com/tidepool-org/platform/data/blood/glucose" + "github.com/tidepool-org/platform/data/deduplicator/deduplicator" + "github.com/tidepool-org/platform/data/types" + "github.com/tidepool-org/platform/data/types/basal" + "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" + "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" + "github.com/tidepool-org/platform/data/types/blood/ketone" + "github.com/tidepool-org/platform/data/types/bolus" + "github.com/tidepool-org/platform/data/types/device" + "github.com/tidepool-org/platform/errors" + migrationMongo "github.com/tidepool-org/platform/migration/mongo" + storeStructuredMongo "github.com/tidepool-org/platform/store/structured/mongo" +) + +func main() { + ctx := context.Background() + ctx, cancel := context.WithCancel(ctx) + defer cancel() + application.RunAndExit(NewMigration(ctx)) +} + +type Migration struct { + ctx context.Context + *migrationMongo.Migration + dataRepository *storeStructuredMongo.Repository +} + +func getValidatedString(bsonData bson.M, fieldName string) (string, error) { + if valRaw, ok := bsonData[fieldName]; !ok { + return "", errors.Newf("%s is missing", fieldName) + } else if val, ok := valRaw.(string); !ok { + return "", errors.Newf("%s is not of expected type", fieldName) + } else if val == "" { + return "", errors.Newf("%s is empty", fieldName) + } else { + return val, nil + } +} + +func getValidatedTime(bsonData bson.M, fieldName string) (time.Time, error) { + if valRaw, ok := bsonData[fieldName]; !ok { + return time.Time{}, errors.Newf("%s is missing", fieldName) + } else if val, ok := valRaw.(time.Time); !ok { + return time.Time{}, errors.Newf("%s is not of expected type", fieldName) + } else if val.IsZero() { + return time.Time{}, errors.Newf("%s is empty", fieldName) + } else { + return val, nil + } +} + +func createDatumHash(bsonData bson.M) (string, error) { + identityFields := []string{} + if datumUserID, err := getValidatedString(bsonData, "_userId"); err != nil { + return "", err + } else { + identityFields = append(identityFields, datumUserID) + } + if deviceID, err := getValidatedString(bsonData, "deviceId"); err != nil { + return "", err + } else { + identityFields = append(identityFields, deviceID) + } + if datumTime, err := getValidatedTime(bsonData, "time"); err != nil { + return "", err + } else { + identityFields = append(identityFields, datumTime.Format(types.TimeFormat)) + } + datumType, err := getValidatedString(bsonData, "type") + if err != nil { + return "", err + } + identityFields = append(identityFields, datumType) + + switch datumType { + case basal.Type: + if deliveryType, err := getValidatedString(bsonData, "deliveryType"); err != nil { + return "", err + } else { + identityFields = append(identityFields, deliveryType) + } + case bolus.Type, device.Type: + if subType, err := getValidatedString(bsonData, "subType"); err != nil { + return "", err + } else { + identityFields = append(identityFields, subType) + } + case selfmonitored.Type, ketone.Type, continuous.Type: + units, err := getValidatedString(bsonData, "units") + if err != nil { + return "", err + } else { + identityFields = append(identityFields, units) + } + + if valueRaw, ok := bsonData["value"]; !ok { + return "", errors.New("value is missing") + } else if val, ok := valueRaw.(float64); !ok { + return "", errors.New("value is not of expected type") + } else { + if units != glucose.MgdL && units != glucose.Mgdl { + // NOTE: we need to ensure the same precision for the + // converted value as it is used to calculate the hash + val = getBGValuePlatformPrecision(val) + } + identityFields = append(identityFields, strconv.FormatFloat(val, 'f', -1, 64)) + } + } + return deduplicator.GenerateIdentityHash(identityFields) +} + +func updateIfExistsPumpSettingsBolus(bsonData bson.M) (interface{}, error) { + dataType, err := getValidatedString(bsonData, "type") + if err != nil { + return nil, err + } + if dataType == "pumpSettings" { + if bolus := bsonData["bolus"]; bolus != nil { + boluses, ok := bolus.(map[string]interface{}) + if !ok { + return nil, errors.Newf("pumpSettings.bolus is not the expected type %v", bolus) + } + return boluses, nil + } + } + return nil, nil +} + +func getBGValuePlatformPrecision(mmolVal float64) float64 { + if len(fmt.Sprintf("%v", mmolVal)) > 7 { + mgdlVal := mmolVal * glucose.MmolLToMgdLConversionFactor + mgdL := glucose.MgdL + mmolVal = *glucose.NormalizeValueForUnits(&mgdlVal, &mgdL) + } + return mmolVal +} + +func NewMigration(ctx context.Context) *Migration { + return &Migration{ + ctx: ctx, + Migration: migrationMongo.NewMigration(), + } +} + +func (m *Migration) Initialize(provider application.Provider) error { + if err := m.Migration.Initialize(provider); err != nil { + return err + } + + m.CLI().Usage = "BACK-37: Migrate all existing data to add required Platform deduplication hash fields" + m.CLI().Description = "BACK-37: To fully migrate devices from the `jellyfish` upload API to the `platform` upload API" + m.CLI().Authors = []cli.Author{ + { + Name: "J H BATE", + Email: "jamie@tidepool.org", + }, + } + + m.CLI().Action = func(ctx *cli.Context) error { + if !m.ParseContext(ctx) { + return nil + } + return m.execute() + } + + return nil +} + +func (m *Migration) execute() error { + m.Logger().Debug("Migrate jellyfish API data") + m.Logger().Debug("Creating data store") + + mongoConfig := m.NewMongoConfig() + mongoConfig.Database = "data" + mongoConfig.Timeout = 60 * time.Minute + dataStore, err := storeStructuredMongo.NewStore(mongoConfig) + if err != nil { + return errors.Wrap(err, "unable to create data store") + } + defer dataStore.Terminate(m.ctx) + + m.Logger().Debug("Creating data repository") + m.dataRepository = dataStore.GetRepository("deviceData") + m.Logger().Info("Migration of jellyfish documents has begun") + hashUpdatedCount, errorCount := m.migrateJellyfishDocuments() + m.Logger().Infof("Migrated %d jellyfish documents", hashUpdatedCount) + m.Logger().Infof("%d errors occurred", errorCount) + + return nil +} + +func (m *Migration) migrateJellyfishDocuments() (int, int) { + logger := m.Logger() + logger.Debug("Finding jellyfish data") + var hashUpdatedCount, errorCount int + selector := bson.M{ + // jellyfish uses a generated _id that is not an mongo objectId + "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, + "_deduplicator": bson.M{"$exists": false}, + } + + var jellyfishResult bson.M + jellyfishDocCursor, err := m.dataRepository.Find(m.ctx, selector) + if err != nil { + logger.WithError(err).Error("Unable to find jellyfish data") + errorCount++ + return hashUpdatedCount, errorCount + } + defer jellyfishDocCursor.Close(m.ctx) + for jellyfishDocCursor.Next(m.ctx) { + err = jellyfishDocCursor.Decode(&jellyfishResult) + if err != nil { + logger.WithError(err).Error("Could not decode mongo doc") + errorCount++ + continue + } + if !m.DryRun() { + if updated, err := m.migrateDocument(jellyfishResult); err != nil { + logger.WithError(err).Errorf("Unable to migrate jellyfish document %s.", jellyfishResult["_id"]) + errorCount++ + continue + } else if updated { + hashUpdatedCount++ + } + } + } + if err := jellyfishDocCursor.Err(); err != nil { + logger.WithError(err).Error("Error while fetching data. Please re-run to complete the migration.") + errorCount++ + } + return hashUpdatedCount, errorCount +} + +func (m *Migration) migrateDocument(jfDatum bson.M) (bool, error) { + + datumID, err := getValidatedString(jfDatum, "_id") + if err != nil { + return false, err + } + + updates := bson.M{} + hash, err := createDatumHash(jfDatum) + if err != nil { + return false, err + } + + updates["_deduplicator"] = bson.M{"hash": hash} + + if boluses, err := updateIfExistsPumpSettingsBolus(jfDatum); err != nil { + return false, err + } else if boluses != nil { + updates["pumpSettings"] = bson.M{"boluses": boluses} + } + + result, err := m.dataRepository.UpdateOne(m.ctx, bson.M{ + "_id": datumID, + "modifiedTime": jfDatum["modifiedTime"], + }, bson.M{ + "$set": updates, + }) + + if err != nil { + return false, err + } + + return result.ModifiedCount == 1, nil +} diff --git a/migrations/back_37/back_37_test.go b/migrations/back_37/back_37_test.go new file mode 100644 index 0000000000..3d3ccc63bf --- /dev/null +++ b/migrations/back_37/back_37_test.go @@ -0,0 +1,110 @@ +package main + +import ( + "reflect" + "testing" + + "go.mongodb.org/mongo-driver/bson" + + pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" +) + +func Test_getBGValuePlatformPrecision(t *testing.T) { + + tests := []struct { + name string + mmolJellyfishVal float64 + mmolPlatformVal float64 + }{ + { + name: "original mmol/L value", + mmolJellyfishVal: 10.1, + mmolPlatformVal: 10.1, + }, + { + name: "converted mgd/L of 100", + mmolJellyfishVal: 5.550747991045533, + mmolPlatformVal: 5.55075, + }, + { + name: "converted mgd/L of 150.0", + mmolJellyfishVal: 8.3261219865683, + mmolPlatformVal: 8.32612, + }, + { + name: "converted mgd/L of 65.0", + mmolJellyfishVal: 3.6079861941795968, + mmolPlatformVal: 3.60799, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := getBGValuePlatformPrecision(tt.mmolJellyfishVal); got != tt.mmolPlatformVal { + t.Errorf("getBGValuePlatformPrecision() mmolJellyfishVal = %v, want %v", got, tt.mmolPlatformVal) + } + }) + } +} + +func Test_updateIfExistsPumpSettingsBolus(t *testing.T) { + type args struct { + bsonData bson.M + } + + bolusData := map[string]interface{}{ + "bolous-1": pumpTest.NewBolus(), + "bolous-2": pumpTest.NewBolus(), + } + + tests := []struct { + name string + args args + want interface{} + wantErr bool + }{ + { + name: "when not pumpSettings", + args: args{ + bsonData: bson.M{"type": "other"}, + }, + want: nil, + wantErr: false, + }, + { + name: "pumpSettings but no bolus", + args: args{ + bsonData: bson.M{"type": "pumpSettings"}, + }, + want: nil, + wantErr: false, + }, + { + name: "pumpSettings bolus wrong type", + args: args{ + bsonData: bson.M{"type": "pumpSettings", "bolus": "wrong"}, + }, + want: nil, + wantErr: true, + }, + { + name: "pumpSettings bolus valid type", + args: args{ + bsonData: bson.M{"type": "pumpSettings", "bolus": bolusData}, + }, + want: bolusData, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := updateIfExistsPumpSettingsBolus(tt.args.bsonData) + if (err != nil) != tt.wantErr { + t.Errorf("updateIfExistsPumpSettingsBolus() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("updateIfExistsPumpSettingsBolus() = %v, want %v", got, tt.want) + } + }) + } +} From 2e310175eb6ac65c5a160a857e3d679a7abe38a2 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 9 Nov 2023 12:38:21 +1300 Subject: [PATCH 004/413] normalize with Days of week --- data/types/settings/pump/sleep_schedule.go | 15 ++++++- dexcom/alert_schedule.go | 51 ++++------------------ dexcom/alert_schedule_test.go | 17 -------- 3 files changed, 22 insertions(+), 61 deletions(-) diff --git a/data/types/settings/pump/sleep_schedule.go b/data/types/settings/pump/sleep_schedule.go index 0da251b14c..a3858bcb74 100644 --- a/data/types/settings/pump/sleep_schedule.go +++ b/data/types/settings/pump/sleep_schedule.go @@ -46,7 +46,14 @@ func (s *SleepScheduleMap) Validate(validator structure.Validator) { } } -func (s *SleepScheduleMap) Normalize(normalizer data.Normalizer) {} +func (s *SleepScheduleMap) Normalize(normalizer data.Normalizer) { + for _, name := range s.sortedNames() { + datumNormalizer := normalizer.WithReference(name) + if datum := s.Get(name); datum != nil { + datum.Normalize(datumNormalizer) + } + } +} func (s *SleepScheduleMap) Get(name string) *SleepSchedule { if datum, exists := (*s)[name]; exists { @@ -106,4 +113,8 @@ func (s *SleepSchedule) Validate(validator structure.Validator) { } } -func (s *SleepSchedule) Normalize(normalizer data.Normalizer) {} +func (s *SleepSchedule) Normalize(normalizer data.Normalizer) { + if s.Days != nil { + sort.Sort(common.DaysOfWeekByDayIndex(*s.Days)) + } +} diff --git a/dexcom/alert_schedule.go b/dexcom/alert_schedule.go index 6236455f7c..68048c9b6c 100644 --- a/dexcom/alert_schedule.go +++ b/dexcom/alert_schedule.go @@ -6,6 +6,7 @@ import ( "strings" "time" + dataTypesCommon "github.com/tidepool-org/platform/data/types/common" dataTypesSettingsCgm "github.com/tidepool-org/platform/data/types/settings/cgm" "github.com/tidepool-org/platform/errors" "github.com/tidepool-org/platform/pointer" @@ -17,13 +18,13 @@ const ( AlertScheduleSettingsStartTimeDefault = "00:00" AlertScheduleSettingsEndTimeDefault = "00:00" - AlertScheduleSettingsDaySunday = "sunday" - AlertScheduleSettingsDayMonday = "monday" - AlertScheduleSettingsDayTuesday = "tuesday" - AlertScheduleSettingsDayWednesday = "wednesday" - AlertScheduleSettingsDayThursday = "thursday" - AlertScheduleSettingsDayFriday = "friday" - AlertScheduleSettingsDaySaturday = "saturday" + AlertScheduleSettingsDaySunday = dataTypesCommon.DaySunday + AlertScheduleSettingsDayMonday = dataTypesCommon.DayMonday + AlertScheduleSettingsDayTuesday = dataTypesCommon.DayTuesday + AlertScheduleSettingsDayWednesday = dataTypesCommon.DayWednesday + AlertScheduleSettingsDayThursday = dataTypesCommon.DayThursday + AlertScheduleSettingsDayFriday = dataTypesCommon.DayFriday + AlertScheduleSettingsDaySaturday = dataTypesCommon.DaySaturday AlertScheduleSettingsOverrideModeUnknown = "unknown" AlertScheduleSettingsOverrideModeQuiet = "quiet" @@ -95,27 +96,6 @@ func AlertScheduleSettingsOverrideModes() []string { } } -func AlertScheduleSettingsDayIndex(day string) int { - switch day { - case AlertScheduleSettingsDaySunday: - return 1 - case AlertScheduleSettingsDayMonday: - return 2 - case AlertScheduleSettingsDayTuesday: - return 3 - case AlertScheduleSettingsDayWednesday: - return 4 - case AlertScheduleSettingsDayThursday: - return 5 - case AlertScheduleSettingsDayFriday: - return 6 - case AlertScheduleSettingsDaySaturday: - return 7 - default: - return 0 - } -} - func AlertSettingAlertNames() []string { return []string{ AlertSettingAlertNameUnknown, @@ -410,7 +390,7 @@ func (a *AlertScheduleSettings) Validate(validator structure.Validator) { func (a *AlertScheduleSettings) Normalize(normalizer structure.Normalizer) { if a.DaysOfWeek != nil { - sort.Sort(DaysOfWeekByAlertScheduleSettingsDayIndex(*a.DaysOfWeek)) + sort.Sort(dataTypesCommon.DaysOfWeekByDayIndex(*a.DaysOfWeek)) } } @@ -418,19 +398,6 @@ func (a *AlertScheduleSettings) IsDefault() bool { return a.Default != nil && *a.Default } -type DaysOfWeekByAlertScheduleSettingsDayIndex []string - -func (d DaysOfWeekByAlertScheduleSettingsDayIndex) Len() int { - return len(d) -} -func (d DaysOfWeekByAlertScheduleSettingsDayIndex) Swap(i int, j int) { - d[i], d[j] = d[j], d[i] -} - -func (d DaysOfWeekByAlertScheduleSettingsDayIndex) Less(i int, j int) bool { - return AlertScheduleSettingsDayIndex(d[i]) < AlertScheduleSettingsDayIndex(d[j]) -} - type AlertSettings []*AlertSetting func ParseAlertSettings(parser structure.ArrayParser) *AlertSettings { diff --git a/dexcom/alert_schedule_test.go b/dexcom/alert_schedule_test.go index 9b9ddef3b5..535f569e8d 100644 --- a/dexcom/alert_schedule_test.go +++ b/dexcom/alert_schedule_test.go @@ -120,23 +120,6 @@ var _ = Describe("Alert", func() { })) }) - Context("AlertScheduleSettingsDayIndex", func() { - DescribeTable("return the expected index when the day", - func(day string, expectedIndex int) { - Expect(dexcom.AlertScheduleSettingsDayIndex(day)).To(Equal(expectedIndex)) - }, - Entry("is an empty string", "", 0), - Entry("is sunday", "sunday", 1), - Entry("is monday", "monday", 2), - Entry("is tuesday", "tuesday", 3), - Entry("is wednesday", "wednesday", 4), - Entry("is thursday", "thursday", 5), - Entry("is friday", "friday", 6), - Entry("is saturday", "saturday", 7), - Entry("is an invalid string", "invalid", 0), - ) - }) - It("AlertSettingAlertNames returns expected", func() { Expect(dexcom.AlertSettingAlertNames()).To(Equal([]string{"unknown", "fall", "high", "low", "noReadings", "outOfRange", "rise", "urgentLow", "urgentLowSoon", "fixedLow"})) Expect(dexcom.AlertSettingAlertNames()).To(Equal([]string{ From 15d432540cbd69d287e51fa59d888d99df85b281 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 10 Nov 2023 10:36:38 +1300 Subject: [PATCH 005/413] tests for sleep schedule migration --- migrations/back_37/back_37.go | 40 +++++++++- migrations/back_37/back_37_test.go | 114 ++++++++++++++++++++++++++++- 2 files changed, 151 insertions(+), 3 deletions(-) diff --git a/migrations/back_37/back_37.go b/migrations/back_37/back_37.go index cc65cc1283..5c8a280ebf 100644 --- a/migrations/back_37/back_37.go +++ b/migrations/back_37/back_37.go @@ -3,7 +3,10 @@ package main import ( "context" "fmt" + "log" + "slices" "strconv" + "strings" "time" "github.com/urfave/cli" @@ -12,13 +15,16 @@ import ( "github.com/tidepool-org/platform/application" "github.com/tidepool-org/platform/data/blood/glucose" "github.com/tidepool-org/platform/data/deduplicator/deduplicator" + "github.com/tidepool-org/platform/data/normalizer" "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/data/types/basal" "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" "github.com/tidepool-org/platform/data/types/blood/ketone" "github.com/tidepool-org/platform/data/types/bolus" + "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/data/types/device" + "github.com/tidepool-org/platform/data/types/settings/pump" "github.com/tidepool-org/platform/errors" migrationMongo "github.com/tidepool-org/platform/migration/mongo" storeStructuredMongo "github.com/tidepool-org/platform/store/structured/mongo" @@ -121,12 +127,44 @@ func createDatumHash(bsonData bson.M) (string, error) { return deduplicator.GenerateIdentityHash(identityFields) } +func updateIfExistsPumpSettingsSleepSchedules(bsonData bson.M) (interface{}, error) { + dataType, err := getValidatedString(bsonData, "type") + if err != nil { + return nil, err + } + + if dataType == pump.Type { + if sleepSchedules := bsonData["sleepSchedules"]; sleepSchedules != nil { + schedules, ok := sleepSchedules.(*pump.SleepScheduleMap) + if !ok { + return nil, errors.Newf("pumpSettings.sleepSchedules is not the expected type %s", sleepSchedules) + } + for key := range *schedules { + days := (*schedules)[key].Days + updatedDays := []string{} + for _, day := range *days { + log.Println("day is: ", day) + if !slices.Contains(common.DaysOfWeek(), strings.ToLower(day)) { + return nil, errors.Newf("pumpSettings.sleepSchedules has an invalid day of week %s", day) + } + updatedDays = append(updatedDays, strings.ToLower(day)) + } + (*schedules)[key].Days = &updatedDays + } + //sorts schedules based on day + schedules.Normalize(normalizer.New()) + return schedules, nil + } + } + return nil, nil +} + func updateIfExistsPumpSettingsBolus(bsonData bson.M) (interface{}, error) { dataType, err := getValidatedString(bsonData, "type") if err != nil { return nil, err } - if dataType == "pumpSettings" { + if dataType == pump.Type { if bolus := bsonData["bolus"]; bolus != nil { boluses, ok := bolus.(map[string]interface{}) if !ok { diff --git a/migrations/back_37/back_37_test.go b/migrations/back_37/back_37_test.go index 3d3ccc63bf..2e35d39269 100644 --- a/migrations/back_37/back_37_test.go +++ b/migrations/back_37/back_37_test.go @@ -2,10 +2,14 @@ package main import ( "reflect" + "strings" "testing" "go.mongodb.org/mongo-driver/bson" + "github.com/tidepool-org/platform/data/normalizer" + "github.com/tidepool-org/platform/data/types/common" + "github.com/tidepool-org/platform/data/types/settings/pump" pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" ) @@ -52,8 +56,8 @@ func Test_updateIfExistsPumpSettingsBolus(t *testing.T) { } bolusData := map[string]interface{}{ - "bolous-1": pumpTest.NewBolus(), - "bolous-2": pumpTest.NewBolus(), + "bolous-1": pumpTest.NewRandomBolus(), + "bolous-2": pumpTest.NewRandomBolus(), } tests := []struct { @@ -108,3 +112,109 @@ func Test_updateIfExistsPumpSettingsBolus(t *testing.T) { }) } } + +func Test_updateIfExistsPumpSettingsSleepSchedules(t *testing.T) { + + type args struct { + bsonData bson.M + } + + sleepSchedulesExpected := &pump.SleepScheduleMap{ + "schedule-1": pumpTest.RandomSleepSchedule(), + "schedule-2": pumpTest.RandomSleepSchedule(), + } + sleepSchedulesStored := pumpTest.CloneSleepSchedules(sleepSchedulesExpected) + sleepSchedulesInvalidDays := pumpTest.CloneSleepSchedules(sleepSchedulesExpected) + + //ensure sorting + sleepSchedulesExpected.Normalize(normalizer.New()) + + s1Days := (*sleepSchedulesStored)["schedule-1"].Days + for key, day := range *s1Days { + (*s1Days)[key] = strings.ToUpper(day) + } + (*sleepSchedulesStored)["schedule-1"].Days = s1Days + + s2Days := (*sleepSchedulesStored)["schedule-2"].Days + + for key, day := range *s2Days { + (*s2Days)[key] = strings.ToUpper(day) + } + (*sleepSchedulesStored)["schedule-2"].Days = s2Days + + (*sleepSchedulesInvalidDays)["schedule-2"].Days = &[]string{"not-a-day", common.DayFriday} + + tests := []struct { + name string + args args + want *pump.SleepScheduleMap + wantErr bool + }{ + { + name: "when not pumpSettings type", + args: args{ + bsonData: bson.M{"type": "other"}, + }, + want: nil, + wantErr: false, + }, + { + name: "pumpSettings but no sleepSchedules", + args: args{ + bsonData: bson.M{"type": "pumpSettings"}, + }, + want: nil, + wantErr: false, + }, + { + name: "pumpSettings sleepSchedules wrong type", + args: args{ + bsonData: bson.M{"type": "pumpSettings", "sleepSchedules": "wrong"}, + }, + want: nil, + wantErr: true, + }, + { + name: "pumpSettings sleepSchedules days invalid", + args: args{ + bsonData: bson.M{"type": "pumpSettings", "sleepSchedules": sleepSchedulesInvalidDays}, + }, + want: nil, + wantErr: true, + }, + { + name: "pumpSettings sleepSchedules valid type", + args: args{ + bsonData: bson.M{"type": "pumpSettings", "sleepSchedules": sleepSchedulesStored}, + }, + want: sleepSchedulesExpected, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := updateIfExistsPumpSettingsSleepSchedules(tt.args.bsonData) + if (err != nil) != tt.wantErr { + t.Errorf("updateIfExistsPumpSettingsSleepSchedules() error = %v, wantErr %v", err, tt.wantErr) + return + } + if tt.want != nil { + gotSleepSchedules, ok := got.(*pump.SleepScheduleMap) + if !ok { + t.Errorf("updateIfExistsPumpSettingsSleepSchedules() = %v, want %v", got, tt.want) + return + } + + for key, wantSchedule := range *tt.want { + if gotSchedule := (*gotSleepSchedules)[key]; gotSchedule != nil { + if !reflect.DeepEqual((*gotSchedule).Days, (*wantSchedule).Days) { + t.Errorf("updateIfExistsPumpSettingsSleepSchedules() = %v, want %v", (*gotSchedule).Days, (*wantSchedule).Days) + } + } else { + t.Errorf("missing schedule %s", key) + } + } + } + }) + } +} From 0c6b55954e038320b89ab916dc11af0c272e1f2b Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 10 Nov 2023 14:32:38 +1300 Subject: [PATCH 006/413] ginkgo tests --- migrations/back_37/back_37.go | 2 - migrations/back_37/back_37_suite_test.go | 11 + migrations/back_37/back_37_test.go | 306 ++++++++--------------- 3 files changed, 118 insertions(+), 201 deletions(-) create mode 100644 migrations/back_37/back_37_suite_test.go diff --git a/migrations/back_37/back_37.go b/migrations/back_37/back_37.go index 5c8a280ebf..86d0cf9e22 100644 --- a/migrations/back_37/back_37.go +++ b/migrations/back_37/back_37.go @@ -3,7 +3,6 @@ package main import ( "context" "fmt" - "log" "slices" "strconv" "strings" @@ -143,7 +142,6 @@ func updateIfExistsPumpSettingsSleepSchedules(bsonData bson.M) (interface{}, err days := (*schedules)[key].Days updatedDays := []string{} for _, day := range *days { - log.Println("day is: ", day) if !slices.Contains(common.DaysOfWeek(), strings.ToLower(day)) { return nil, errors.Newf("pumpSettings.sleepSchedules has an invalid day of week %s", day) } diff --git a/migrations/back_37/back_37_suite_test.go b/migrations/back_37/back_37_suite_test.go new file mode 100644 index 0000000000..3dc91eb5de --- /dev/null +++ b/migrations/back_37/back_37_suite_test.go @@ -0,0 +1,11 @@ +package main + +import ( + "testing" + + "github.com/tidepool-org/platform/test" +) + +func TestSuite(t *testing.T) { + test.Test(t) +} diff --git a/migrations/back_37/back_37_test.go b/migrations/back_37/back_37_test.go index 2e35d39269..04ede0919e 100644 --- a/migrations/back_37/back_37_test.go +++ b/migrations/back_37/back_37_test.go @@ -1,10 +1,10 @@ package main import ( - "reflect" "strings" - "testing" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" "go.mongodb.org/mongo-driver/bson" "github.com/tidepool-org/platform/data/normalizer" @@ -13,208 +13,116 @@ import ( pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" ) -func Test_getBGValuePlatformPrecision(t *testing.T) { - - tests := []struct { - name string - mmolJellyfishVal float64 - mmolPlatformVal float64 - }{ - { - name: "original mmol/L value", - mmolJellyfishVal: 10.1, - mmolPlatformVal: 10.1, - }, - { - name: "converted mgd/L of 100", - mmolJellyfishVal: 5.550747991045533, - mmolPlatformVal: 5.55075, - }, - { - name: "converted mgd/L of 150.0", - mmolJellyfishVal: 8.3261219865683, - mmolPlatformVal: 8.32612, - }, - { - name: "converted mgd/L of 65.0", - mmolJellyfishVal: 3.6079861941795968, - mmolPlatformVal: 3.60799, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := getBGValuePlatformPrecision(tt.mmolJellyfishVal); got != tt.mmolPlatformVal { - t.Errorf("getBGValuePlatformPrecision() mmolJellyfishVal = %v, want %v", got, tt.mmolPlatformVal) - } - }) - } -} - -func Test_updateIfExistsPumpSettingsBolus(t *testing.T) { - type args struct { - bsonData bson.M - } - - bolusData := map[string]interface{}{ - "bolous-1": pumpTest.NewRandomBolus(), - "bolous-2": pumpTest.NewRandomBolus(), - } - - tests := []struct { - name string - args args - want interface{} - wantErr bool - }{ - { - name: "when not pumpSettings", - args: args{ - bsonData: bson.M{"type": "other"}, - }, - want: nil, - wantErr: false, - }, - { - name: "pumpSettings but no bolus", - args: args{ - bsonData: bson.M{"type": "pumpSettings"}, - }, - want: nil, - wantErr: false, - }, - { - name: "pumpSettings bolus wrong type", - args: args{ - bsonData: bson.M{"type": "pumpSettings", "bolus": "wrong"}, - }, - want: nil, - wantErr: true, - }, - { - name: "pumpSettings bolus valid type", - args: args{ - bsonData: bson.M{"type": "pumpSettings", "bolus": bolusData}, +var _ = Describe("back-37", func() { + + Context("getBGValuePlatformPrecision", func() { + DescribeTable("return the expected mmol/L value", + func(jellyfishVal float64, expectedVal float64) { + actual := getBGValuePlatformPrecision(jellyfishVal) + Expect(actual).To(Equal(expectedVal)) }, - want: bolusData, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := updateIfExistsPumpSettingsBolus(tt.args.bsonData) - if (err != nil) != tt.wantErr { - t.Errorf("updateIfExistsPumpSettingsBolus() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("updateIfExistsPumpSettingsBolus() = %v, want %v", got, tt.want) + Entry("original mmol/L value", 10.1, 10.1), + Entry("converted mgd/L of 100", 5.550747991045533, 5.55075), + Entry("converted mgd/L of 150", 8.3261219865683, 8.32612), + Entry("converted mgd/L of 65", 3.6079861941795968, 3.60799), + ) + }) + + Context("updateIfExistsPumpSettingsBolus", func() { + var bolusData map[string]interface{} + + BeforeEach(func() { + bolusData = map[string]interface{}{ + "bolous-1": pumpTest.NewRandomBolus(), + "bolous-2": pumpTest.NewRandomBolus(), } + Expect(bolusData).ToNot(BeNil()) }) - } -} - -func Test_updateIfExistsPumpSettingsSleepSchedules(t *testing.T) { - - type args struct { - bsonData bson.M - } - - sleepSchedulesExpected := &pump.SleepScheduleMap{ - "schedule-1": pumpTest.RandomSleepSchedule(), - "schedule-2": pumpTest.RandomSleepSchedule(), - } - sleepSchedulesStored := pumpTest.CloneSleepSchedules(sleepSchedulesExpected) - sleepSchedulesInvalidDays := pumpTest.CloneSleepSchedules(sleepSchedulesExpected) - - //ensure sorting - sleepSchedulesExpected.Normalize(normalizer.New()) - - s1Days := (*sleepSchedulesStored)["schedule-1"].Days - for key, day := range *s1Days { - (*s1Days)[key] = strings.ToUpper(day) - } - (*sleepSchedulesStored)["schedule-1"].Days = s1Days - - s2Days := (*sleepSchedulesStored)["schedule-2"].Days - - for key, day := range *s2Days { - (*s2Days)[key] = strings.ToUpper(day) - } - (*sleepSchedulesStored)["schedule-2"].Days = s2Days - - (*sleepSchedulesInvalidDays)["schedule-2"].Days = &[]string{"not-a-day", common.DayFriday} - - tests := []struct { - name string - args args - want *pump.SleepScheduleMap - wantErr bool - }{ - { - name: "when not pumpSettings type", - args: args{ - bsonData: bson.M{"type": "other"}, - }, - want: nil, - wantErr: false, - }, - { - name: "pumpSettings but no sleepSchedules", - args: args{ - bsonData: bson.M{"type": "pumpSettings"}, - }, - want: nil, - wantErr: false, - }, - { - name: "pumpSettings sleepSchedules wrong type", - args: args{ - bsonData: bson.M{"type": "pumpSettings", "sleepSchedules": "wrong"}, - }, - want: nil, - wantErr: true, - }, - { - name: "pumpSettings sleepSchedules days invalid", - args: args{ - bsonData: bson.M{"type": "pumpSettings", "sleepSchedules": sleepSchedulesInvalidDays}, - }, - want: nil, - wantErr: true, - }, - { - name: "pumpSettings sleepSchedules valid type", - args: args{ - bsonData: bson.M{"type": "pumpSettings", "sleepSchedules": sleepSchedulesStored}, - }, - want: sleepSchedulesExpected, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := updateIfExistsPumpSettingsSleepSchedules(tt.args.bsonData) - if (err != nil) != tt.wantErr { - t.Errorf("updateIfExistsPumpSettingsSleepSchedules() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.want != nil { - gotSleepSchedules, ok := got.(*pump.SleepScheduleMap) - if !ok { - t.Errorf("updateIfExistsPumpSettingsSleepSchedules() = %v, want %v", got, tt.want) + + DescribeTable("should", + func(input bson.M, expected interface{}, expectError bool) { + actual, err := updateIfExistsPumpSettingsBolus(input) + if expectError { + Expect(err).ToNot(BeNil()) + Expect(actual).To(BeNil()) return } - - for key, wantSchedule := range *tt.want { - if gotSchedule := (*gotSleepSchedules)[key]; gotSchedule != nil { - if !reflect.DeepEqual((*gotSchedule).Days, (*wantSchedule).Days) { - t.Errorf("updateIfExistsPumpSettingsSleepSchedules() = %v, want %v", (*gotSchedule).Days, (*wantSchedule).Days) - } - } else { - t.Errorf("missing schedule %s", key) - } + Expect(err).To(BeNil()) + if expected != nil { + Expect(actual).To(Equal(expected)) + } else { + Expect(actual).To(BeNil()) } + }, + Entry("do nothing when wrong type", bson.M{"type": "other"}, nil, false), + Entry("do nothing when has no bolus", bson.M{"type": "pumpSettings"}, nil, false), + Entry("error when bolus is invalid", bson.M{"type": "pumpSettings", "bolus": "wrong"}, nil, true), + Entry("return bolus when valid", bson.M{"type": "pumpSettings", "bolus": bolusData}, bolusData, false), + ) + }) + + Context("updateIfExistsPumpSettingsSleepSchedules", func() { + var sleepSchedulesExpected *pump.SleepScheduleMap + var sleepSchedulesStored *pump.SleepScheduleMap + var sleepSchedulesInvalidDays *pump.SleepScheduleMap + + BeforeEach(func() { + sleepSchedulesExpected = &pump.SleepScheduleMap{ + "schedule-1": pumpTest.RandomSleepSchedule(), + "schedule-2": pumpTest.RandomSleepSchedule(), + } + sleepSchedulesInvalidDays = pumpTest.CloneSleepSchedules(sleepSchedulesExpected) + (*sleepSchedulesInvalidDays)["schedule-2"].Days = &[]string{"not-a-day", common.DayFriday} + + sleepSchedulesStored = pumpTest.CloneSleepSchedules(sleepSchedulesExpected) + + s1Days := (*sleepSchedulesStored)["schedule-1"].Days + for key, day := range *s1Days { + (*s1Days)[key] = strings.ToUpper(day) } + (*sleepSchedulesStored)["schedule-1"].Days = s1Days + + s2Days := (*sleepSchedulesStored)["schedule-2"].Days + for key, day := range *s2Days { + (*s2Days)[key] = strings.ToUpper(day) + } + (*sleepSchedulesStored)["schedule-2"].Days = s2Days + + //ensure sorting + sleepSchedulesExpected.Normalize(normalizer.New()) + + Expect(sleepSchedulesExpected).ToNot(BeNil()) + Expect(sleepSchedulesStored).ToNot(BeNil()) + Expect(sleepSchedulesInvalidDays).ToNot(BeNil()) + }) + + It("does nothing when wrong type", func() { + actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "other"}) + Expect(err).To(BeNil()) + Expect(actual).To(BeNil()) + }) + It("does nothing when no sleepSchedules", func() { + actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "pumpSettings"}) + Expect(err).To(BeNil()) + Expect(actual).To(BeNil()) + }) + It("returns error when sleepSchedules is invalid", func() { + actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "pumpSettings", "sleepSchedules": "wrong"}) + Expect(err).ToNot(BeNil()) + Expect(actual).To(BeNil()) + }) + It("returns updated sleepSchedules when valid", func() { + actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "pumpSettings", "sleepSchedules": sleepSchedulesStored}) + Expect(err).To(BeNil()) + Expect(actual).ToNot(BeNil()) + actualSchedules, ok := actual.(*pump.SleepScheduleMap) + Expect(ok).To(BeTrue()) + Expect(actualSchedules).To(Equal(sleepSchedulesExpected)) + }) + It("returns updated sleepSchedules when valid", func() { + actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "pumpSettings", "sleepSchedules": sleepSchedulesInvalidDays}) + Expect(err).ToNot(BeNil()) + Expect(actual).To(BeNil()) }) - } -} + }) +}) From 9a7010a4c1d684787aad7311a3ba2b2ba661e050 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 14 Nov 2023 16:39:52 +1300 Subject: [PATCH 007/413] did tests break build? --- migrations/back_37/back_37_suite_test.go | 14 +- migrations/back_37/back_37_test.go | 252 +++++++++++------------ 2 files changed, 133 insertions(+), 133 deletions(-) diff --git a/migrations/back_37/back_37_suite_test.go b/migrations/back_37/back_37_suite_test.go index 3dc91eb5de..d06b4e0421 100644 --- a/migrations/back_37/back_37_suite_test.go +++ b/migrations/back_37/back_37_suite_test.go @@ -1,11 +1,11 @@ package main -import ( - "testing" +// import ( +// "testing" - "github.com/tidepool-org/platform/test" -) +// "github.com/tidepool-org/platform/test" +// ) -func TestSuite(t *testing.T) { - test.Test(t) -} +// func TestSuite(t *testing.T) { +// test.Test(t) +// } diff --git a/migrations/back_37/back_37_test.go b/migrations/back_37/back_37_test.go index 04ede0919e..25e9741889 100644 --- a/migrations/back_37/back_37_test.go +++ b/migrations/back_37/back_37_test.go @@ -1,128 +1,128 @@ package main -import ( - "strings" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "go.mongodb.org/mongo-driver/bson" - - "github.com/tidepool-org/platform/data/normalizer" - "github.com/tidepool-org/platform/data/types/common" - "github.com/tidepool-org/platform/data/types/settings/pump" - pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" -) - -var _ = Describe("back-37", func() { - - Context("getBGValuePlatformPrecision", func() { - DescribeTable("return the expected mmol/L value", - func(jellyfishVal float64, expectedVal float64) { - actual := getBGValuePlatformPrecision(jellyfishVal) - Expect(actual).To(Equal(expectedVal)) - }, - Entry("original mmol/L value", 10.1, 10.1), - Entry("converted mgd/L of 100", 5.550747991045533, 5.55075), - Entry("converted mgd/L of 150", 8.3261219865683, 8.32612), - Entry("converted mgd/L of 65", 3.6079861941795968, 3.60799), - ) - }) - - Context("updateIfExistsPumpSettingsBolus", func() { - var bolusData map[string]interface{} - - BeforeEach(func() { - bolusData = map[string]interface{}{ - "bolous-1": pumpTest.NewRandomBolus(), - "bolous-2": pumpTest.NewRandomBolus(), - } - Expect(bolusData).ToNot(BeNil()) - }) - - DescribeTable("should", - func(input bson.M, expected interface{}, expectError bool) { - actual, err := updateIfExistsPumpSettingsBolus(input) - if expectError { - Expect(err).ToNot(BeNil()) - Expect(actual).To(BeNil()) - return - } - Expect(err).To(BeNil()) - if expected != nil { - Expect(actual).To(Equal(expected)) - } else { - Expect(actual).To(BeNil()) - } - }, - Entry("do nothing when wrong type", bson.M{"type": "other"}, nil, false), - Entry("do nothing when has no bolus", bson.M{"type": "pumpSettings"}, nil, false), - Entry("error when bolus is invalid", bson.M{"type": "pumpSettings", "bolus": "wrong"}, nil, true), - Entry("return bolus when valid", bson.M{"type": "pumpSettings", "bolus": bolusData}, bolusData, false), - ) - }) - - Context("updateIfExistsPumpSettingsSleepSchedules", func() { - var sleepSchedulesExpected *pump.SleepScheduleMap - var sleepSchedulesStored *pump.SleepScheduleMap - var sleepSchedulesInvalidDays *pump.SleepScheduleMap - - BeforeEach(func() { - sleepSchedulesExpected = &pump.SleepScheduleMap{ - "schedule-1": pumpTest.RandomSleepSchedule(), - "schedule-2": pumpTest.RandomSleepSchedule(), - } - sleepSchedulesInvalidDays = pumpTest.CloneSleepSchedules(sleepSchedulesExpected) - (*sleepSchedulesInvalidDays)["schedule-2"].Days = &[]string{"not-a-day", common.DayFriday} - - sleepSchedulesStored = pumpTest.CloneSleepSchedules(sleepSchedulesExpected) - - s1Days := (*sleepSchedulesStored)["schedule-1"].Days - for key, day := range *s1Days { - (*s1Days)[key] = strings.ToUpper(day) - } - (*sleepSchedulesStored)["schedule-1"].Days = s1Days - - s2Days := (*sleepSchedulesStored)["schedule-2"].Days - for key, day := range *s2Days { - (*s2Days)[key] = strings.ToUpper(day) - } - (*sleepSchedulesStored)["schedule-2"].Days = s2Days - - //ensure sorting - sleepSchedulesExpected.Normalize(normalizer.New()) - - Expect(sleepSchedulesExpected).ToNot(BeNil()) - Expect(sleepSchedulesStored).ToNot(BeNil()) - Expect(sleepSchedulesInvalidDays).ToNot(BeNil()) - }) - - It("does nothing when wrong type", func() { - actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "other"}) - Expect(err).To(BeNil()) - Expect(actual).To(BeNil()) - }) - It("does nothing when no sleepSchedules", func() { - actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "pumpSettings"}) - Expect(err).To(BeNil()) - Expect(actual).To(BeNil()) - }) - It("returns error when sleepSchedules is invalid", func() { - actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "pumpSettings", "sleepSchedules": "wrong"}) - Expect(err).ToNot(BeNil()) - Expect(actual).To(BeNil()) - }) - It("returns updated sleepSchedules when valid", func() { - actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "pumpSettings", "sleepSchedules": sleepSchedulesStored}) - Expect(err).To(BeNil()) - Expect(actual).ToNot(BeNil()) - actualSchedules, ok := actual.(*pump.SleepScheduleMap) - Expect(ok).To(BeTrue()) - Expect(actualSchedules).To(Equal(sleepSchedulesExpected)) - }) - It("returns updated sleepSchedules when valid", func() { - actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "pumpSettings", "sleepSchedules": sleepSchedulesInvalidDays}) - Expect(err).ToNot(BeNil()) - Expect(actual).To(BeNil()) - }) - }) -}) +// import ( +// "strings" + +// . "github.com/onsi/ginkgo/v2" +// . "github.com/onsi/gomega" +// "go.mongodb.org/mongo-driver/bson" + +// "github.com/tidepool-org/platform/data/normalizer" +// "github.com/tidepool-org/platform/data/types/common" +// "github.com/tidepool-org/platform/data/types/settings/pump" +// pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" +// ) + +// var _ = Describe("back-37", func() { + +// Context("getBGValuePlatformPrecision", func() { +// DescribeTable("return the expected mmol/L value", +// func(jellyfishVal float64, expectedVal float64) { +// actual := getBGValuePlatformPrecision(jellyfishVal) +// Expect(actual).To(Equal(expectedVal)) +// }, +// Entry("original mmol/L value", 10.1, 10.1), +// Entry("converted mgd/L of 100", 5.550747991045533, 5.55075), +// Entry("converted mgd/L of 150", 8.3261219865683, 8.32612), +// Entry("converted mgd/L of 65", 3.6079861941795968, 3.60799), +// ) +// }) + +// Context("updateIfExistsPumpSettingsBolus", func() { +// var bolusData map[string]interface{} + +// BeforeEach(func() { +// bolusData = map[string]interface{}{ +// "bolous-1": pumpTest.NewRandomBolus(), +// "bolous-2": pumpTest.NewRandomBolus(), +// } +// Expect(bolusData).ToNot(BeNil()) +// }) + +// DescribeTable("should", +// func(input bson.M, expected interface{}, expectError bool) { +// actual, err := updateIfExistsPumpSettingsBolus(input) +// if expectError { +// Expect(err).ToNot(BeNil()) +// Expect(actual).To(BeNil()) +// return +// } +// Expect(err).To(BeNil()) +// if expected != nil { +// Expect(actual).To(Equal(expected)) +// } else { +// Expect(actual).To(BeNil()) +// } +// }, +// Entry("do nothing when wrong type", bson.M{"type": "other"}, nil, false), +// Entry("do nothing when has no bolus", bson.M{"type": "pumpSettings"}, nil, false), +// Entry("error when bolus is invalid", bson.M{"type": "pumpSettings", "bolus": "wrong"}, nil, true), +// Entry("return bolus when valid", bson.M{"type": "pumpSettings", "bolus": bolusData}, bolusData, false), +// ) +// }) + +// Context("updateIfExistsPumpSettingsSleepSchedules", func() { +// var sleepSchedulesExpected *pump.SleepScheduleMap +// var sleepSchedulesStored *pump.SleepScheduleMap +// var sleepSchedulesInvalidDays *pump.SleepScheduleMap + +// BeforeEach(func() { +// sleepSchedulesExpected = &pump.SleepScheduleMap{ +// "schedule-1": pumpTest.RandomSleepSchedule(), +// "schedule-2": pumpTest.RandomSleepSchedule(), +// } +// sleepSchedulesInvalidDays = pumpTest.CloneSleepSchedules(sleepSchedulesExpected) +// (*sleepSchedulesInvalidDays)["schedule-2"].Days = &[]string{"not-a-day", common.DayFriday} + +// sleepSchedulesStored = pumpTest.CloneSleepSchedules(sleepSchedulesExpected) + +// s1Days := (*sleepSchedulesStored)["schedule-1"].Days +// for key, day := range *s1Days { +// (*s1Days)[key] = strings.ToUpper(day) +// } +// (*sleepSchedulesStored)["schedule-1"].Days = s1Days + +// s2Days := (*sleepSchedulesStored)["schedule-2"].Days +// for key, day := range *s2Days { +// (*s2Days)[key] = strings.ToUpper(day) +// } +// (*sleepSchedulesStored)["schedule-2"].Days = s2Days + +// //ensure sorting +// sleepSchedulesExpected.Normalize(normalizer.New()) + +// Expect(sleepSchedulesExpected).ToNot(BeNil()) +// Expect(sleepSchedulesStored).ToNot(BeNil()) +// Expect(sleepSchedulesInvalidDays).ToNot(BeNil()) +// }) + +// It("does nothing when wrong type", func() { +// actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "other"}) +// Expect(err).To(BeNil()) +// Expect(actual).To(BeNil()) +// }) +// It("does nothing when no sleepSchedules", func() { +// actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "pumpSettings"}) +// Expect(err).To(BeNil()) +// Expect(actual).To(BeNil()) +// }) +// It("returns error when sleepSchedules is invalid", func() { +// actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "pumpSettings", "sleepSchedules": "wrong"}) +// Expect(err).ToNot(BeNil()) +// Expect(actual).To(BeNil()) +// }) +// It("returns updated sleepSchedules when valid", func() { +// actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "pumpSettings", "sleepSchedules": sleepSchedulesStored}) +// Expect(err).To(BeNil()) +// Expect(actual).ToNot(BeNil()) +// actualSchedules, ok := actual.(*pump.SleepScheduleMap) +// Expect(ok).To(BeTrue()) +// Expect(actualSchedules).To(Equal(sleepSchedulesExpected)) +// }) +// It("returns updated sleepSchedules when valid", func() { +// actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "pumpSettings", "sleepSchedules": sleepSchedulesInvalidDays}) +// Expect(err).ToNot(BeNil()) +// Expect(actual).To(BeNil()) +// }) +// }) +// }) From b8afa84a5050970b0d70cb822048ec1f0aa917cb Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 16 Nov 2023 10:18:57 +1300 Subject: [PATCH 008/413] move tests into seperate namespace --- migrations/back_37/back_37.go | 188 ++------------- migrations/back_37/back_37_suite_test.go | 11 - migrations/back_37/back_37_test.go | 128 ---------- migrations/back_37/utils/utils.go | 191 +++++++++++++++ migrations/back_37/utils/utils_suite_test.go | 11 + migrations/back_37/utils/utils_test.go | 231 +++++++++++++++++++ 6 files changed, 454 insertions(+), 306 deletions(-) delete mode 100644 migrations/back_37/back_37_suite_test.go delete mode 100644 migrations/back_37/back_37_test.go create mode 100644 migrations/back_37/utils/utils.go create mode 100644 migrations/back_37/utils/utils_suite_test.go create mode 100644 migrations/back_37/utils/utils_test.go diff --git a/migrations/back_37/back_37.go b/migrations/back_37/back_37.go index 86d0cf9e22..7424a9eef5 100644 --- a/migrations/back_37/back_37.go +++ b/migrations/back_37/back_37.go @@ -2,30 +2,15 @@ package main import ( "context" - "fmt" - "slices" - "strconv" - "strings" "time" "github.com/urfave/cli" "go.mongodb.org/mongo-driver/bson" "github.com/tidepool-org/platform/application" - "github.com/tidepool-org/platform/data/blood/glucose" - "github.com/tidepool-org/platform/data/deduplicator/deduplicator" - "github.com/tidepool-org/platform/data/normalizer" - "github.com/tidepool-org/platform/data/types" - "github.com/tidepool-org/platform/data/types/basal" - "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" - "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" - "github.com/tidepool-org/platform/data/types/blood/ketone" - "github.com/tidepool-org/platform/data/types/bolus" - "github.com/tidepool-org/platform/data/types/common" - "github.com/tidepool-org/platform/data/types/device" - "github.com/tidepool-org/platform/data/types/settings/pump" "github.com/tidepool-org/platform/errors" migrationMongo "github.com/tidepool-org/platform/migration/mongo" + "github.com/tidepool-org/platform/migrations/back_37/utils" storeStructuredMongo "github.com/tidepool-org/platform/store/structured/mongo" ) @@ -42,147 +27,6 @@ type Migration struct { dataRepository *storeStructuredMongo.Repository } -func getValidatedString(bsonData bson.M, fieldName string) (string, error) { - if valRaw, ok := bsonData[fieldName]; !ok { - return "", errors.Newf("%s is missing", fieldName) - } else if val, ok := valRaw.(string); !ok { - return "", errors.Newf("%s is not of expected type", fieldName) - } else if val == "" { - return "", errors.Newf("%s is empty", fieldName) - } else { - return val, nil - } -} - -func getValidatedTime(bsonData bson.M, fieldName string) (time.Time, error) { - if valRaw, ok := bsonData[fieldName]; !ok { - return time.Time{}, errors.Newf("%s is missing", fieldName) - } else if val, ok := valRaw.(time.Time); !ok { - return time.Time{}, errors.Newf("%s is not of expected type", fieldName) - } else if val.IsZero() { - return time.Time{}, errors.Newf("%s is empty", fieldName) - } else { - return val, nil - } -} - -func createDatumHash(bsonData bson.M) (string, error) { - identityFields := []string{} - if datumUserID, err := getValidatedString(bsonData, "_userId"); err != nil { - return "", err - } else { - identityFields = append(identityFields, datumUserID) - } - if deviceID, err := getValidatedString(bsonData, "deviceId"); err != nil { - return "", err - } else { - identityFields = append(identityFields, deviceID) - } - if datumTime, err := getValidatedTime(bsonData, "time"); err != nil { - return "", err - } else { - identityFields = append(identityFields, datumTime.Format(types.TimeFormat)) - } - datumType, err := getValidatedString(bsonData, "type") - if err != nil { - return "", err - } - identityFields = append(identityFields, datumType) - - switch datumType { - case basal.Type: - if deliveryType, err := getValidatedString(bsonData, "deliveryType"); err != nil { - return "", err - } else { - identityFields = append(identityFields, deliveryType) - } - case bolus.Type, device.Type: - if subType, err := getValidatedString(bsonData, "subType"); err != nil { - return "", err - } else { - identityFields = append(identityFields, subType) - } - case selfmonitored.Type, ketone.Type, continuous.Type: - units, err := getValidatedString(bsonData, "units") - if err != nil { - return "", err - } else { - identityFields = append(identityFields, units) - } - - if valueRaw, ok := bsonData["value"]; !ok { - return "", errors.New("value is missing") - } else if val, ok := valueRaw.(float64); !ok { - return "", errors.New("value is not of expected type") - } else { - if units != glucose.MgdL && units != glucose.Mgdl { - // NOTE: we need to ensure the same precision for the - // converted value as it is used to calculate the hash - val = getBGValuePlatformPrecision(val) - } - identityFields = append(identityFields, strconv.FormatFloat(val, 'f', -1, 64)) - } - } - return deduplicator.GenerateIdentityHash(identityFields) -} - -func updateIfExistsPumpSettingsSleepSchedules(bsonData bson.M) (interface{}, error) { - dataType, err := getValidatedString(bsonData, "type") - if err != nil { - return nil, err - } - - if dataType == pump.Type { - if sleepSchedules := bsonData["sleepSchedules"]; sleepSchedules != nil { - schedules, ok := sleepSchedules.(*pump.SleepScheduleMap) - if !ok { - return nil, errors.Newf("pumpSettings.sleepSchedules is not the expected type %s", sleepSchedules) - } - for key := range *schedules { - days := (*schedules)[key].Days - updatedDays := []string{} - for _, day := range *days { - if !slices.Contains(common.DaysOfWeek(), strings.ToLower(day)) { - return nil, errors.Newf("pumpSettings.sleepSchedules has an invalid day of week %s", day) - } - updatedDays = append(updatedDays, strings.ToLower(day)) - } - (*schedules)[key].Days = &updatedDays - } - //sorts schedules based on day - schedules.Normalize(normalizer.New()) - return schedules, nil - } - } - return nil, nil -} - -func updateIfExistsPumpSettingsBolus(bsonData bson.M) (interface{}, error) { - dataType, err := getValidatedString(bsonData, "type") - if err != nil { - return nil, err - } - if dataType == pump.Type { - if bolus := bsonData["bolus"]; bolus != nil { - boluses, ok := bolus.(map[string]interface{}) - if !ok { - return nil, errors.Newf("pumpSettings.bolus is not the expected type %v", bolus) - } - return boluses, nil - } - } - return nil, nil -} - -func getBGValuePlatformPrecision(mmolVal float64) float64 { - if len(fmt.Sprintf("%v", mmolVal)) > 7 { - mgdlVal := mmolVal * glucose.MmolLToMgdLConversionFactor - mgdL := glucose.MgdL - mmolVal = *glucose.NormalizeValueForUnits(&mgdlVal, &mgdL) - } - return mmolVal -} - func NewMigration(ctx context.Context) *Migration { return &Migration{ ctx: ctx, @@ -281,24 +125,35 @@ func (m *Migration) migrateJellyfishDocuments() (int, int) { func (m *Migration) migrateDocument(jfDatum bson.M) (bool, error) { - datumID, err := getValidatedString(jfDatum, "_id") + datumID, err := utils.GetValidatedString(jfDatum, "_id") if err != nil { return false, err } - updates := bson.M{} - hash, err := createDatumHash(jfDatum) + // updates := bson.M{} + // hash, err := utils.CreateDatumHash(jfDatum) + // if err != nil { + // return false, err + // } + + // updates["_deduplicator"] = bson.M{"hash": hash} + + updates, err := utils.GetDatumUpdates(jfDatum) if err != nil { return false, err } - updates["_deduplicator"] = bson.M{"hash": hash} + // if boluses, err := utils.UpdateIfExistsPumpSettingsBolus(jfDatum); err != nil { + // return false, err + // } else if boluses != nil { + // updates["boluses"] = boluses + // } - if boluses, err := updateIfExistsPumpSettingsBolus(jfDatum); err != nil { - return false, err - } else if boluses != nil { - updates["pumpSettings"] = bson.M{"boluses": boluses} - } + // if sleepSchedules, err := utils.UpdateIfExistsPumpSettingsSleepSchedules(jfDatum); err != nil { + // return false, err + // } else if sleepSchedules != nil { + // updates["sleepSchedules"] = sleepSchedules + // } result, err := m.dataRepository.UpdateOne(m.ctx, bson.M{ "_id": datumID, @@ -310,6 +165,5 @@ func (m *Migration) migrateDocument(jfDatum bson.M) (bool, error) { if err != nil { return false, err } - return result.ModifiedCount == 1, nil } diff --git a/migrations/back_37/back_37_suite_test.go b/migrations/back_37/back_37_suite_test.go deleted file mode 100644 index d06b4e0421..0000000000 --- a/migrations/back_37/back_37_suite_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package main - -// import ( -// "testing" - -// "github.com/tidepool-org/platform/test" -// ) - -// func TestSuite(t *testing.T) { -// test.Test(t) -// } diff --git a/migrations/back_37/back_37_test.go b/migrations/back_37/back_37_test.go deleted file mode 100644 index 25e9741889..0000000000 --- a/migrations/back_37/back_37_test.go +++ /dev/null @@ -1,128 +0,0 @@ -package main - -// import ( -// "strings" - -// . "github.com/onsi/ginkgo/v2" -// . "github.com/onsi/gomega" -// "go.mongodb.org/mongo-driver/bson" - -// "github.com/tidepool-org/platform/data/normalizer" -// "github.com/tidepool-org/platform/data/types/common" -// "github.com/tidepool-org/platform/data/types/settings/pump" -// pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" -// ) - -// var _ = Describe("back-37", func() { - -// Context("getBGValuePlatformPrecision", func() { -// DescribeTable("return the expected mmol/L value", -// func(jellyfishVal float64, expectedVal float64) { -// actual := getBGValuePlatformPrecision(jellyfishVal) -// Expect(actual).To(Equal(expectedVal)) -// }, -// Entry("original mmol/L value", 10.1, 10.1), -// Entry("converted mgd/L of 100", 5.550747991045533, 5.55075), -// Entry("converted mgd/L of 150", 8.3261219865683, 8.32612), -// Entry("converted mgd/L of 65", 3.6079861941795968, 3.60799), -// ) -// }) - -// Context("updateIfExistsPumpSettingsBolus", func() { -// var bolusData map[string]interface{} - -// BeforeEach(func() { -// bolusData = map[string]interface{}{ -// "bolous-1": pumpTest.NewRandomBolus(), -// "bolous-2": pumpTest.NewRandomBolus(), -// } -// Expect(bolusData).ToNot(BeNil()) -// }) - -// DescribeTable("should", -// func(input bson.M, expected interface{}, expectError bool) { -// actual, err := updateIfExistsPumpSettingsBolus(input) -// if expectError { -// Expect(err).ToNot(BeNil()) -// Expect(actual).To(BeNil()) -// return -// } -// Expect(err).To(BeNil()) -// if expected != nil { -// Expect(actual).To(Equal(expected)) -// } else { -// Expect(actual).To(BeNil()) -// } -// }, -// Entry("do nothing when wrong type", bson.M{"type": "other"}, nil, false), -// Entry("do nothing when has no bolus", bson.M{"type": "pumpSettings"}, nil, false), -// Entry("error when bolus is invalid", bson.M{"type": "pumpSettings", "bolus": "wrong"}, nil, true), -// Entry("return bolus when valid", bson.M{"type": "pumpSettings", "bolus": bolusData}, bolusData, false), -// ) -// }) - -// Context("updateIfExistsPumpSettingsSleepSchedules", func() { -// var sleepSchedulesExpected *pump.SleepScheduleMap -// var sleepSchedulesStored *pump.SleepScheduleMap -// var sleepSchedulesInvalidDays *pump.SleepScheduleMap - -// BeforeEach(func() { -// sleepSchedulesExpected = &pump.SleepScheduleMap{ -// "schedule-1": pumpTest.RandomSleepSchedule(), -// "schedule-2": pumpTest.RandomSleepSchedule(), -// } -// sleepSchedulesInvalidDays = pumpTest.CloneSleepSchedules(sleepSchedulesExpected) -// (*sleepSchedulesInvalidDays)["schedule-2"].Days = &[]string{"not-a-day", common.DayFriday} - -// sleepSchedulesStored = pumpTest.CloneSleepSchedules(sleepSchedulesExpected) - -// s1Days := (*sleepSchedulesStored)["schedule-1"].Days -// for key, day := range *s1Days { -// (*s1Days)[key] = strings.ToUpper(day) -// } -// (*sleepSchedulesStored)["schedule-1"].Days = s1Days - -// s2Days := (*sleepSchedulesStored)["schedule-2"].Days -// for key, day := range *s2Days { -// (*s2Days)[key] = strings.ToUpper(day) -// } -// (*sleepSchedulesStored)["schedule-2"].Days = s2Days - -// //ensure sorting -// sleepSchedulesExpected.Normalize(normalizer.New()) - -// Expect(sleepSchedulesExpected).ToNot(BeNil()) -// Expect(sleepSchedulesStored).ToNot(BeNil()) -// Expect(sleepSchedulesInvalidDays).ToNot(BeNil()) -// }) - -// It("does nothing when wrong type", func() { -// actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "other"}) -// Expect(err).To(BeNil()) -// Expect(actual).To(BeNil()) -// }) -// It("does nothing when no sleepSchedules", func() { -// actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "pumpSettings"}) -// Expect(err).To(BeNil()) -// Expect(actual).To(BeNil()) -// }) -// It("returns error when sleepSchedules is invalid", func() { -// actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "pumpSettings", "sleepSchedules": "wrong"}) -// Expect(err).ToNot(BeNil()) -// Expect(actual).To(BeNil()) -// }) -// It("returns updated sleepSchedules when valid", func() { -// actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "pumpSettings", "sleepSchedules": sleepSchedulesStored}) -// Expect(err).To(BeNil()) -// Expect(actual).ToNot(BeNil()) -// actualSchedules, ok := actual.(*pump.SleepScheduleMap) -// Expect(ok).To(BeTrue()) -// Expect(actualSchedules).To(Equal(sleepSchedulesExpected)) -// }) -// It("returns updated sleepSchedules when valid", func() { -// actual, err := updateIfExistsPumpSettingsSleepSchedules(bson.M{"type": "pumpSettings", "sleepSchedules": sleepSchedulesInvalidDays}) -// Expect(err).ToNot(BeNil()) -// Expect(actual).To(BeNil()) -// }) -// }) -// }) diff --git a/migrations/back_37/utils/utils.go b/migrations/back_37/utils/utils.go new file mode 100644 index 0000000000..f267517eb7 --- /dev/null +++ b/migrations/back_37/utils/utils.go @@ -0,0 +1,191 @@ +package utils + +import ( + "fmt" + "slices" + "strconv" + "strings" + "time" + + "github.com/tidepool-org/platform/data/blood/glucose" + "github.com/tidepool-org/platform/data/deduplicator/deduplicator" + "github.com/tidepool-org/platform/data/normalizer" + "github.com/tidepool-org/platform/data/types" + "github.com/tidepool-org/platform/data/types/basal" + "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" + "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" + "github.com/tidepool-org/platform/data/types/blood/ketone" + "github.com/tidepool-org/platform/data/types/bolus" + "github.com/tidepool-org/platform/data/types/common" + "github.com/tidepool-org/platform/data/types/device" + "github.com/tidepool-org/platform/data/types/settings/pump" + "github.com/tidepool-org/platform/errors" + "go.mongodb.org/mongo-driver/bson" +) + +func GetValidatedString(bsonData bson.M, fieldName string) (string, error) { + if valRaw, ok := bsonData[fieldName]; !ok { + return "", errors.Newf("%s is missing", fieldName) + } else if val, ok := valRaw.(string); !ok { + return "", errors.Newf("%s is not of expected type", fieldName) + } else if val == "" { + return "", errors.Newf("%s is empty", fieldName) + } else { + return val, nil + } +} + +func getValidatedTime(bsonData bson.M, fieldName string) (time.Time, error) { + if valRaw, ok := bsonData[fieldName]; !ok { + return time.Time{}, errors.Newf("%s is missing", fieldName) + } else if val, ok := valRaw.(time.Time); !ok { + return time.Time{}, errors.Newf("%s is not of expected type", fieldName) + } else if val.IsZero() { + return time.Time{}, errors.Newf("%s is empty", fieldName) + } else { + return val, nil + } +} + +func datumHash(bsonData bson.M) (string, error) { + identityFields := []string{} + if datumUserID, err := GetValidatedString(bsonData, "_userId"); err != nil { + return "", err + } else { + identityFields = append(identityFields, datumUserID) + } + if deviceID, err := GetValidatedString(bsonData, "deviceId"); err != nil { + return "", err + } else { + identityFields = append(identityFields, deviceID) + } + if datumTime, err := getValidatedTime(bsonData, "time"); err != nil { + return "", err + } else { + identityFields = append(identityFields, datumTime.Format(types.TimeFormat)) + } + datumType, err := GetValidatedString(bsonData, "type") + if err != nil { + return "", err + } + identityFields = append(identityFields, datumType) + + switch datumType { + case basal.Type: + if deliveryType, err := GetValidatedString(bsonData, "deliveryType"); err != nil { + return "", err + } else { + identityFields = append(identityFields, deliveryType) + } + case bolus.Type, device.Type: + if subType, err := GetValidatedString(bsonData, "subType"); err != nil { + return "", err + } else { + identityFields = append(identityFields, subType) + } + case selfmonitored.Type, ketone.Type, continuous.Type: + units, err := GetValidatedString(bsonData, "units") + if err != nil { + return "", err + } else { + identityFields = append(identityFields, units) + } + + if valueRaw, ok := bsonData["value"]; !ok { + return "", errors.New("value is missing") + } else if val, ok := valueRaw.(float64); !ok { + return "", errors.New("value is not of expected type") + } else { + if units != glucose.MgdL && units != glucose.Mgdl { + // NOTE: we need to ensure the same precision for the + // converted value as it is used to calculate the hash + val = GetBGValuePlatformPrecision(val) + } + identityFields = append(identityFields, strconv.FormatFloat(val, 'f', -1, 64)) + } + } + return deduplicator.GenerateIdentityHash(identityFields) +} + +func updateIfExistsPumpSettingsSleepSchedules(bsonData bson.M) (*pump.SleepScheduleMap, error) { + dataType, err := GetValidatedString(bsonData, "type") + if err != nil { + return nil, err + } + + if dataType == pump.Type { + if sleepSchedules := bsonData["sleepSchedules"]; sleepSchedules != nil { + schedules, ok := sleepSchedules.(*pump.SleepScheduleMap) + if !ok { + return nil, errors.Newf("pumpSettings.sleepSchedules is not the expected type %s", sleepSchedules) + } + for key := range *schedules { + days := (*schedules)[key].Days + updatedDays := []string{} + for _, day := range *days { + if !slices.Contains(common.DaysOfWeek(), strings.ToLower(day)) { + return nil, errors.Newf("pumpSettings.sleepSchedules has an invalid day of week %s", day) + } + updatedDays = append(updatedDays, strings.ToLower(day)) + } + (*schedules)[key].Days = &updatedDays + } + //sorts schedules based on day + schedules.Normalize(normalizer.New()) + return schedules, nil + } + } + return nil, nil +} + +func updateIfExistsPumpSettingsBolus(bsonData bson.M) (*pump.BolusMap, error) { + dataType, err := GetValidatedString(bsonData, "type") + if err != nil { + return nil, err + } + if dataType == pump.Type { + if bolus := bsonData["bolus"]; bolus != nil { + boluses, ok := bolus.(*pump.BolusMap) + if !ok { + return nil, errors.Newf("pumpSettings.bolus is not the expected type %v", bolus) + } + return boluses, nil + } + } + return nil, nil +} + +func GetBGValuePlatformPrecision(mmolVal float64) float64 { + if len(fmt.Sprintf("%v", mmolVal)) > 7 { + mgdlVal := mmolVal * glucose.MmolLToMgdLConversionFactor + mgdL := glucose.MgdL + mmolVal = *glucose.NormalizeValueForUnits(&mgdlVal, &mgdL) + } + return mmolVal +} + +func GetDatumUpdates(bsonData bson.M) (bson.M, error) { + updates := bson.M{} + + hash, err := datumHash(bsonData) + if err != nil { + return nil, err + } + updates["_deduplicator"] = bson.M{"hash": hash} + + boluses, err := updateIfExistsPumpSettingsBolus(bsonData) + if err != nil { + return nil, err + } else if boluses != nil { + updates["boluses"] = boluses + } + + sleepSchedules, err := updateIfExistsPumpSettingsSleepSchedules(bsonData) + if err != nil { + return nil, err + } else if sleepSchedules != nil { + updates["sleepSchedules"] = sleepSchedules + } + + return updates, nil +} diff --git a/migrations/back_37/utils/utils_suite_test.go b/migrations/back_37/utils/utils_suite_test.go new file mode 100644 index 0000000000..a7f980d288 --- /dev/null +++ b/migrations/back_37/utils/utils_suite_test.go @@ -0,0 +1,11 @@ +package utils_test + +import ( + "testing" + + "github.com/tidepool-org/platform/test" +) + +func TestSuite(t *testing.T) { + test.Test(t) +} diff --git a/migrations/back_37/utils/utils_test.go b/migrations/back_37/utils/utils_test.go new file mode 100644 index 0000000000..ab37794c86 --- /dev/null +++ b/migrations/back_37/utils/utils_test.go @@ -0,0 +1,231 @@ +package utils_test + +import ( + "strings" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "go.mongodb.org/mongo-driver/bson" + + "github.com/tidepool-org/platform/data/normalizer" + "github.com/tidepool-org/platform/data/types/common" + "github.com/tidepool-org/platform/data/types/settings/pump" + pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" + "github.com/tidepool-org/platform/migrations/back_37/utils" +) + +var _ = Describe("back-37", func() { + + var _ = Describe("utils", func() { + + Context("GetBGValuePlatformPrecision", func() { + DescribeTable("return the expected mmol/L value", + func(jellyfishVal float64, expectedVal float64) { + actual := utils.GetBGValuePlatformPrecision(jellyfishVal) + Expect(actual).To(Equal(expectedVal)) + }, + Entry("original mmol/L value", 10.1, 10.1), + Entry("converted mgd/L of 100", 5.550747991045533, 5.55075), + Entry("converted mgd/L of 150", 8.3261219865683, 8.32612), + Entry("converted mgd/L of 65", 3.6079861941795968, 3.60799), + ) + }) + + var _ = Describe("GetDatumUpdates", func() { + var existingDatum bson.M + + BeforeEach(func() { + existingDatum = bson.M{} + existingDatum["_userId"] = "some-user-id" + existingDatum["deviceId"] = "some-device-id" + theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") + existingDatum["time"] = theTime + existingDatum["type"] = "bolous" + Expect(existingDatum).ToNot(BeNil()) + }) + Context("_deduplicator hash", func() { + DescribeTable("should", + func(getInput func() bson.M, expected bson.M, expectError bool) { + input := getInput() + actual, err := utils.GetDatumUpdates(input) + if expectError { + Expect(err).ToNot(BeNil()) + Expect(actual).To(BeNil()) + return + } + Expect(err).To(BeNil()) + if expected != nil { + Expect(actual).To(Equal(expected)) + } else { + Expect(actual).To(BeNil()) + } + }, + Entry("error when missing _userId", func() bson.M { + existingDatum["_userId"] = nil + return existingDatum + }, nil, true), + Entry("error when missing deviceId", func() bson.M { + existingDatum["deviceId"] = nil + return existingDatum + }, nil, true), + Entry("error when missing time", func() bson.M { + existingDatum["time"] = nil + return existingDatum + }, nil, true), + Entry("error when missing type", func() bson.M { + existingDatum["type"] = nil + return existingDatum + }, nil, true), + Entry("adds hash when vaild", func() bson.M { + return existingDatum + }, bson.M{"_deduplicator": bson.M{"hash": "fDOlBxqBW5/iv5zV1Rcsawt4wpiSoHdd/yf5WAXW4/c="}}, false), + ) + }) + + Context("bolus", func() { + var bolusData = &pump.BolusMap{ + "bolus-1": pumpTest.NewRandomBolus(), + "bolus-2": pumpTest.NewRandomBolus(), + } + var bolusDatum bson.M + + BeforeEach(func() { + bolusDatum = existingDatum + bolusDatum["type"] = "pumpSettings" + bolusDatum["bolus"] = bolusData + }) + + DescribeTable("should", + func(getInput func() bson.M, expected bson.M, expectError bool) { + input := getInput() + actual, err := utils.GetDatumUpdates(input) + if expectError { + Expect(err).ToNot(BeNil()) + Expect(actual).To(BeNil()) + return + } + Expect(err).To(BeNil()) + if expected != nil { + Expect(actual).To(BeEquivalentTo(expected)) + } else { + Expect(actual).To(BeNil()) + } + }, + + Entry("do nothing when wrong type", + func() bson.M { + bolusDatum["type"] = "other" + return bolusDatum + }, + bson.M{"_deduplicator": bson.M{"hash": "eZburze+ZpJwbBfrNLtugyZybLY1WJH22dWAoVBpyvg="}}, + false, + ), + Entry("do nothing when has no bolus", + func() bson.M { + bolusDatum["bolus"] = nil + return bolusDatum + }, + bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}, + false, + ), + Entry("error bolus when invalid", + func() bson.M { + bolusDatum["bolus"] = "wrong" + return bolusDatum + }, + nil, + true, + ), + Entry("add boluses when bolus found", + func() bson.M { + bolusDatum["bolus"] = bolusData + return bolusDatum + }, + bson.M{ + "_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}, + "boluses": bolusData, + }, + false, + ), + ) + }) + Context("sleepSchedules", func() { + var sleepSchedulesExpected *pump.SleepScheduleMap + var sleepSchedulesStored *pump.SleepScheduleMap + var sleepSchedulesInvalidDays *pump.SleepScheduleMap + var sleepSchedulesDatum bson.M + + BeforeEach(func() { + + sleepSchedulesDatum = existingDatum + sleepSchedulesDatum["type"] = "pumpSettings" + sleepSchedulesExpected = &pump.SleepScheduleMap{ + "schedule-1": pumpTest.RandomSleepSchedule(), + "schedule-2": pumpTest.RandomSleepSchedule(), + } + sleepSchedulesInvalidDays = pumpTest.CloneSleepSchedules(sleepSchedulesExpected) + (*sleepSchedulesInvalidDays)["schedule-2"].Days = &[]string{"not-a-day", common.DayFriday} + + sleepSchedulesStored = pumpTest.CloneSleepSchedules(sleepSchedulesExpected) + + s1Days := (*sleepSchedulesStored)["schedule-1"].Days + for key, day := range *s1Days { + (*s1Days)[key] = strings.ToUpper(day) + } + (*sleepSchedulesStored)["schedule-1"].Days = s1Days + + s2Days := (*sleepSchedulesStored)["schedule-2"].Days + for key, day := range *s2Days { + (*s2Days)[key] = strings.ToUpper(day) + } + (*sleepSchedulesStored)["schedule-2"].Days = s2Days + + //ensure sorting + sleepSchedulesExpected.Normalize(normalizer.New()) + + Expect(sleepSchedulesExpected).ToNot(BeNil()) + Expect(sleepSchedulesStored).ToNot(BeNil()) + Expect(sleepSchedulesExpected).ToNot(Equal(sleepSchedulesStored)) + Expect(sleepSchedulesInvalidDays).ToNot(BeNil()) + }) + + It("does nothing when wrong type", func() { + sleepSchedulesDatum["type"] = "other" + actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) + Expect(err).To(BeNil()) + Expect(actual).To(Equal(bson.M{"_deduplicator": bson.M{"hash": "eZburze+ZpJwbBfrNLtugyZybLY1WJH22dWAoVBpyvg="}})) + }) + It("does nothing when no sleepSchedules", func() { + sleepSchedulesDatum["sleepSchedules"] = nil + actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) + Expect(err).To(BeNil()) + Expect(actual).To(Equal(bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}})) + }) + It("returns error when sleepSchedules is invalid", func() { + sleepSchedulesDatum["sleepSchedules"] = "wrong" + actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(Equal("pumpSettings.sleepSchedules is not the expected type wrong")) + Expect(actual).To(BeNil()) + }) + It("returns updated sleepSchedules when valid", func() { + Expect(sleepSchedulesExpected).ToNot(Equal(sleepSchedulesStored)) + sleepSchedulesDatum["sleepSchedules"] = sleepSchedulesStored + actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) + Expect(err).To(BeNil()) + Expect(actual).ToNot(BeNil()) + Expect(actual["sleepSchedules"]).ToNot(BeNil()) + Expect(actual["sleepSchedules"]).To(Equal(sleepSchedulesExpected)) + }) + It("returns error when sleepSchedules have invalid days", func() { + sleepSchedulesDatum["sleepSchedules"] = sleepSchedulesInvalidDays + actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(Equal("pumpSettings.sleepSchedules has an invalid day of week not-a-day")) + Expect(actual).To(BeNil()) + }) + }) + }) + }) +}) From 1dffd87a8e043502e42cf0c41f2f33cba21760f1 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 16 Nov 2023 12:16:38 +1300 Subject: [PATCH 009/413] import order --- migrations/back_37/utils/utils.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/migrations/back_37/utils/utils.go b/migrations/back_37/utils/utils.go index f267517eb7..c12e92c4c0 100644 --- a/migrations/back_37/utils/utils.go +++ b/migrations/back_37/utils/utils.go @@ -7,6 +7,8 @@ import ( "strings" "time" + "go.mongodb.org/mongo-driver/bson" + "github.com/tidepool-org/platform/data/blood/glucose" "github.com/tidepool-org/platform/data/deduplicator/deduplicator" "github.com/tidepool-org/platform/data/normalizer" @@ -20,7 +22,6 @@ import ( "github.com/tidepool-org/platform/data/types/device" "github.com/tidepool-org/platform/data/types/settings/pump" "github.com/tidepool-org/platform/errors" - "go.mongodb.org/mongo-driver/bson" ) func GetValidatedString(bsonData bson.M, fieldName string) (string, error) { From 47b7c2f00316d6f20d4d5512793b67c9220c34f2 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 16 Nov 2023 16:23:15 +1300 Subject: [PATCH 010/413] fix for prescription tests --- data/types/settings/pump/test/pump.go | 2 +- prescription/test/prescription.go | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/data/types/settings/pump/test/pump.go b/data/types/settings/pump/test/pump.go index 1f5314544d..07645b70ef 100644 --- a/data/types/settings/pump/test/pump.go +++ b/data/types/settings/pump/test/pump.go @@ -48,7 +48,7 @@ func NewPump(unitsBloodGlucose *string) *pump.Pump { datum.BloodGlucoseTargetPreprandial = dataBloodGlucoseTest.RandomTarget(unitsBloodGlucose) datum.BloodGlucoseTargetSchedules = pump.NewBloodGlucoseTargetStartArrayMap() datum.BloodGlucoseTargetSchedules.Set(scheduleName, RandomBloodGlucoseTargetStartArray(unitsBloodGlucose)) - datum.Boluses = NewRandomBolusMap(2, 4) + datum.Bolus = NewRandomBolus() datum.CarbohydrateRatioSchedules = pump.NewCarbohydrateRatioStartArrayMap() datum.CarbohydrateRatioSchedules.Set(scheduleName, NewCarbohydrateRatioStartArray()) datum.Display = NewDisplay() diff --git a/prescription/test/prescription.go b/prescription/test/prescription.go index a3ace93185..0120d9d221 100644 --- a/prescription/test/prescription.go +++ b/prescription/test/prescription.go @@ -4,15 +4,12 @@ import ( "fmt" "time" - dataTypesSettingsPump "github.com/tidepool-org/platform/data/types/settings/pump" - dataBloodGlucoseTest "github.com/tidepool-org/platform/data/blood/glucose/test" "github.com/tidepool-org/platform/data/types/settings/pump" "github.com/google/uuid" "github.com/tidepool-org/platform/data/blood/glucose" - testUtils "github.com/tidepool-org/platform/test" userTest "github.com/tidepool-org/platform/user/test" @@ -183,7 +180,7 @@ func RandomInitialSettings() *prescription.InitialSettings { func RandomCalculator() *prescription.Calculator { return &prescription.Calculator{ - Method: pointer.FromString(testUtils.RandomStringFromArray(prescription.AllowedCalculatorMethods())), + Method: pointer.FromString(test.RandomStringFromArray(prescription.AllowedCalculatorMethods())), RecommendedBasalRate: pointer.FromFloat64(test.RandomFloat64FromRange(0, 100)), RecommendedCarbohydrateRatio: pointer.FromFloat64(test.RandomFloat64FromRange(0, 100)), RecommendedInsulinSensitivity: pointer.FromFloat64(test.RandomFloat64FromRange(0, 100)), @@ -238,10 +235,10 @@ func RandomBloodGlucoseTargetStart(startMinimum int) *pump.BloodGlucoseTargetSta func RandomInsulinModel() *string { validInsulinTypes := []string{ - dataTypesSettingsPump.InsulinModelModelTypeRapidAdult, - dataTypesSettingsPump.InsulinModelModelTypeRapidChild, + pump.InsulinModelModelTypeRapidAdult, + pump.InsulinModelModelTypeRapidChild, } - return pointer.FromString(testUtils.RandomStringFromArray(validInsulinTypes)) + return pointer.FromString(test.RandomStringFromArray(validInsulinTypes)) } func RandomDeviceID() string { From 4bc6f48c32f4643a6d367cebe49135ecb176c243 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 21 Nov 2023 09:54:07 +1300 Subject: [PATCH 011/413] cleanup --- migrations/back_37/back_37.go | 21 --------------------- migrations/back_37/utils/utils_test.go | 2 -- 2 files changed, 23 deletions(-) diff --git a/migrations/back_37/back_37.go b/migrations/back_37/back_37.go index 7424a9eef5..4e0a2652bc 100644 --- a/migrations/back_37/back_37.go +++ b/migrations/back_37/back_37.go @@ -77,7 +77,6 @@ func (m *Migration) execute() error { hashUpdatedCount, errorCount := m.migrateJellyfishDocuments() m.Logger().Infof("Migrated %d jellyfish documents", hashUpdatedCount) m.Logger().Infof("%d errors occurred", errorCount) - return nil } @@ -130,31 +129,11 @@ func (m *Migration) migrateDocument(jfDatum bson.M) (bool, error) { return false, err } - // updates := bson.M{} - // hash, err := utils.CreateDatumHash(jfDatum) - // if err != nil { - // return false, err - // } - - // updates["_deduplicator"] = bson.M{"hash": hash} - updates, err := utils.GetDatumUpdates(jfDatum) if err != nil { return false, err } - // if boluses, err := utils.UpdateIfExistsPumpSettingsBolus(jfDatum); err != nil { - // return false, err - // } else if boluses != nil { - // updates["boluses"] = boluses - // } - - // if sleepSchedules, err := utils.UpdateIfExistsPumpSettingsSleepSchedules(jfDatum); err != nil { - // return false, err - // } else if sleepSchedules != nil { - // updates["sleepSchedules"] = sleepSchedules - // } - result, err := m.dataRepository.UpdateOne(m.ctx, bson.M{ "_id": datumID, "modifiedTime": jfDatum["modifiedTime"], diff --git a/migrations/back_37/utils/utils_test.go b/migrations/back_37/utils/utils_test.go index ab37794c86..5ab72ba022 100644 --- a/migrations/back_37/utils/utils_test.go +++ b/migrations/back_37/utils/utils_test.go @@ -16,9 +16,7 @@ import ( ) var _ = Describe("back-37", func() { - var _ = Describe("utils", func() { - Context("GetBGValuePlatformPrecision", func() { DescribeTable("return the expected mmol/L value", func(jellyfishVal float64, expectedVal float64) { From 350e785458115ae788fc888b94fd258f948cac85 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 28 Nov 2023 13:30:49 +1300 Subject: [PATCH 012/413] initial rework for robust data migration --- .../20231128_jellyfish_migration.go | 381 ++++++++++++++++++ .../utils/utils.go | 0 .../utils/utils_suite_test.go | 0 .../utils/utils_test.go | 2 +- migrations/back_37/back_37.go | 148 ------- 5 files changed, 382 insertions(+), 149 deletions(-) create mode 100644 migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go rename migrations/{back_37 => 20231128_jellyfish_migration}/utils/utils.go (100%) rename migrations/{back_37 => 20231128_jellyfish_migration}/utils/utils_suite_test.go (100%) rename migrations/{back_37 => 20231128_jellyfish_migration}/utils/utils_test.go (98%) delete mode 100644 migrations/back_37/back_37.go diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go new file mode 100644 index 0000000000..cec3773e52 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -0,0 +1,381 @@ +package main + +import ( + "context" + "fmt" + "math" + "time" + + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + + "github.com/tidepool-org/platform/application" + migrationMongo "github.com/tidepool-org/platform/migration/mongo" + "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" + "github.com/urfave/cli" +) + +type Config struct { + uri string + minOplogWindow int + // these values are used to determine writes batches, first dividing the oplog's size with the desired duration and + // expected entry size, then adding a divisor to account for NOP overshoot in the oplog + expectedOplogEntrySize int + // how much of the oplog is NOP, this adjusts the batch to account for an oplog that is very change sensitive + // must be > 0 + // prod 0.6 + // idle 100 + nopPercent int + // minimum free disk space percent + minFreePercent int + readBatchSize int64 +} + +type Migration struct { + ctx context.Context + config *Config + *migrationMongo.Migration + client *mongo.Client + oplogC *mongo.Collection + deviceDataC *mongo.Collection + writeBatchSize *int64 + updates []mongo.WriteModel +} + +const oplogName = "oplog.rs" + +func main() { + ctx := context.Background() + ctx, cancel := context.WithCancel(ctx) + defer cancel() + application.RunAndExit(NewMigration(ctx)) +} + +func NewMigration(ctx context.Context) *Migration { + return &Migration{ + ctx: ctx, + Migration: migrationMongo.NewMigration(), + config: &Config{}, + updates: []mongo.WriteModel{}, + } +} + +func (m *Migration) Initialize(provider application.Provider) error { + if err := m.Migration.Initialize(provider); err != nil { + return err + } + + m.CLI().Usage = "BACK-37: Migrate all existing data to add required Platform deduplication hash fields" + m.CLI().Description = "BACK-37: To fully migrate devices from the `jellyfish` upload API to the `platform` upload API" + m.CLI().Authors = []cli.Author{ + { + Name: "J H BATE", + Email: "jamie@tidepool.org", + }, + } + m.CLI().Flags = append(m.CLI().Flags, + cli.Int64Flag{ + Name: "batch-size", + Usage: "number of records to read each time", + Destination: &m.config.readBatchSize, + Value: 3000, + Required: false, + }, + cli.IntFlag{ + Name: "min-free-percent", + Usage: "minimum free disk space percent", + Destination: &m.config.minFreePercent, + Value: 10, + Required: false, + }, + cli.IntFlag{ + Name: "nop-percent", + Usage: "how much of the oplog is NOP", + Destination: &m.config.nopPercent, + Value: 100, + Required: false, + }, + cli.IntFlag{ + Name: "oplog-entry-size", + Usage: "minimum free disk space percent", + Destination: &m.config.expectedOplogEntrySize, + Value: 420, + Required: false, + }, + cli.IntFlag{ + Name: "oplog-window", + Usage: "minimum oplog window in seconds", + Destination: &m.config.minOplogWindow, + Value: 28800, // 8hrs + Required: false, + }, + cli.StringFlag{ + Name: "uri", + Usage: "mongo connection URI", + Destination: &m.config.uri, + Value: "mongodb://localhost:27017", + Required: false, + }, + ) + + m.CLI().Action = func(ctx *cli.Context) error { + if !m.ParseContext(ctx) { + return nil + } + if err := m.prepare(); err != nil { + return nil + } + return m.execute() + } + return nil +} + +func (m *Migration) prepare() error { + var err error + m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(m.config.uri)) + if err != nil { + return fmt.Errorf("unable to connect to MongoDB: %w", err) + } + defer m.client.Disconnect(m.ctx) + + m.oplogC = m.client.Database("local").Collection(oplogName) + m.deviceDataC = m.client.Database("data").Collection("deviceData") + + if err := m.checkFreeSpace(); err != nil { + return err + } + + err = m.setWriteBatchSize() + if err != nil { + return err + } + return nil +} + +func (m *Migration) execute() error { + totalMigrated := 0 + for m.fetchAndUpdateBatch() { + updatedCount, err := m.writeBatchUpdates() + if err != nil { + m.Logger().WithError(err).Error("failed writing batch") + return err + } + totalMigrated = totalMigrated + updatedCount + m.Logger().Debugf("migrated %d for a total of %d migrated items", updatedCount, totalMigrated) + } + return nil +} + +func (m *Migration) getOplogDuration() (time.Duration, error) { + type MongoMetaData struct { + Wall time.Time `json:"wall"` + } + if m.oplogC != nil { + var oldest MongoMetaData + if err := m.oplogC.FindOne( + m.ctx, bson.M{}, + options.FindOne().SetSort("$natural"), + options.FindOne().SetProjection(bson.M{"wall": 1})).Decode(&oldest); err != nil { + return 0, err + } + var newest MongoMetaData + if err := m.oplogC.FindOne(m.ctx, + bson.M{}, + options.FindOne().SetSort("-$natural"), + options.FindOne().SetProjection(bson.M{"wall": 1})).Decode(&newest); err != nil { + return 0, err + } + oplogDuration := oldest.Wall.Sub(oldest.Wall) + m.Logger().Debugf("oplog duration is currently: %v\n", oplogDuration) + return oplogDuration, nil + } + m.Logger().Debug("Not clustered, not retrieving oplog duration.") + oplogDuration := time.Duration(m.config.minOplogWindow+1) * time.Second + return oplogDuration, nil + +} + +func (m *Migration) setWriteBatchSize() error { + if m.oplogC != nil { + m.Logger().Debug("Getting oplog duration...") + type MongoMetaData struct { + MaxSize int `json:"maxSize"` + } + var metaData MongoMetaData + if err := m.oplogC.Database().RunCommand(m.ctx, bson.M{"collStats": oplogName}).Decode(&metaData); err != nil { + return err + } + writeBatchSize := int64(metaData.MaxSize / m.config.expectedOplogEntrySize / m.config.minOplogWindow / (m.config.nopPercent / 7)) + m.writeBatchSize = &writeBatchSize + return nil + } + var writeBatchSize = int64(30000) + m.Logger().Debugf("MongoDB is not clustered, removing write batch limit, setting to %d documents.", writeBatchSize) + m.writeBatchSize = &writeBatchSize + return nil +} + +func (m *Migration) checkFreeSpace() error { + type MongoMetaData struct { + FsTotalSize int `json:"fsTotalSize"` + FsUsedSize int `json:"fsUsedSize"` + } + var metaData MongoMetaData + m.Logger().Debug("Getting DB free space...") + err := m.deviceDataC.Database().RunCommand(m.ctx, bson.M{"dbStats": 1}).Decode(&metaData) + if err != nil { + return err + } + bytesFree := metaData.FsTotalSize - metaData.FsUsedSize + percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) + m.Logger().Debugf("DB disk currently has %d%% (%d) free.", percentFree*100, bytesFree) + + if percentFree > m.config.minFreePercent { + return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) + } + return nil +} + +func (m *Migration) getWaitTime() (float64, error) { + m.Logger().Debug("Loading DB replication status...") + + type Member struct { + Name string `json:"name"` + Health int `json:"health"` + Uptime int `json:"uptime"` + State int `json:"state"` + } + + type MongoMetaData struct { + Members []Member `json:"members"` + } + + var metaData MongoMetaData + m.client.Database("admin").RunCommand(m.ctx, bson.M{"replSetGetStatus": 1}).Decode(&metaData) + m.Logger().Debug("DB replication status loaded.") + + for _, member := range metaData.Members { + if member.State < 1 || member.State > 2 || member.Health != 1 || member.Uptime < 120 { + m.Logger().Debugf("DB member %s down or not ready.", member.Name) + return 240, nil + } + } + + oplogDuration, err := m.getOplogDuration() + if err != nil { + return 0, err + } + if oplogDuration.Seconds() < float64(m.config.minOplogWindow) { + minOplogWindowTime := time.Duration(m.config.minOplogWindow) * time.Second + m.Logger().Debugf("DB OPLOG shorter than requested duration of %s, currently %s.", minOplogWindowTime, oplogDuration) + waitTime := float64(m.config.minOplogWindow) - oplogDuration.Seconds() + waitTime *= 1.15 + if waitTime < 600 { + waitTime = 600 + } + return waitTime, nil + } + return 0, nil +} + +func (m *Migration) blockUntilDBReady() error { + waitTime, err := m.getWaitTime() + if err != nil { + return err + } + var totalWait float64 + for waitTime > 0 { + totalWait += waitTime + if totalWait > 1800 { + m.Logger().Debugf("Long total wait of %s, possibly high load, or sustained DB outage. If neither, adjust NOP_PERCENT to reduce overshoot.", time.Duration(totalWait)*time.Second) + } + m.Logger().Debugf("Sleeping for %d", time.Duration(waitTime)*time.Second) + time.Sleep(time.Duration(waitTime) * time.Second) + waitTime, err = m.getWaitTime() + if err != nil { + return err + } + } + return nil +} + +func (m *Migration) fetchAndUpdateBatch() bool { + selector := bson.M{ + // jellyfish uses a generated _id that is not an mongo objectId + "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, + "_deduplicator": bson.M{"$exists": false}, + } + m.updates = []mongo.WriteModel{} + + dDataCursor, err := m.deviceDataC.Find(m.ctx, selector, + &options.FindOptions{Limit: &m.config.readBatchSize}, + ) + if err != nil { + m.Logger().WithError(err).Error("failed to select data") + return false + } + + var dDataResult bson.M + + defer dDataCursor.Close(m.ctx) + for dDataCursor.Next(m.ctx) { + err = dDataCursor.Decode(&dDataResult) + if err != nil { + m.Logger().WithError(err).Error("failed decoding data") + return false + } + + datumID, err := utils.GetValidatedString(dDataResult, "_id") + if err != nil { + m.Logger().WithError(err).Error("failed getting dutum _id") + return false + } + + updates, err := utils.GetDatumUpdates(dDataResult) + if err != nil { + m.Logger().WithError(err).Error("failed getting datum updates") + return false + } + + m.updates = append(m.updates, mongo.NewUpdateOneModel().SetFilter( + bson.M{ + "_id": datumID, + "modifiedTime": dDataResult["modifiedTime"], + }).SetUpdate(bson.M{ + "$set": updates, + })) + } + return len(m.updates) > 0 +} + +func (m *Migration) writeBatchUpdates() (int, error) { + var getBatches = func(chunkSize int) [][]mongo.WriteModel { + batches := [][]mongo.WriteModel{} + for i := 0; i < len(m.updates); i += chunkSize { + end := i + chunkSize + + if end > len(m.updates) { + end = len(m.updates) + } + batches = append(batches, m.updates[i:end]) + } + return batches + } + + updateCount := 0 + for _, batch := range getBatches(int(*m.writeBatchSize)) { + if err := m.blockUntilDBReady(); err != nil { + return updateCount, err + } + if err := m.checkFreeSpace(); err != nil { + return updateCount, err + } + results, err := m.deviceDataC.BulkWrite(m.ctx, batch) + if err != nil { + return updateCount, err + } + updateCount = updateCount + int(results.ModifiedCount) + } + return updateCount, nil +} diff --git a/migrations/back_37/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go similarity index 100% rename from migrations/back_37/utils/utils.go rename to migrations/20231128_jellyfish_migration/utils/utils.go diff --git a/migrations/back_37/utils/utils_suite_test.go b/migrations/20231128_jellyfish_migration/utils/utils_suite_test.go similarity index 100% rename from migrations/back_37/utils/utils_suite_test.go rename to migrations/20231128_jellyfish_migration/utils/utils_suite_test.go diff --git a/migrations/back_37/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go similarity index 98% rename from migrations/back_37/utils/utils_test.go rename to migrations/20231128_jellyfish_migration/utils/utils_test.go index 5ab72ba022..deff2cbfcc 100644 --- a/migrations/back_37/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -12,7 +12,7 @@ import ( "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/data/types/settings/pump" pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" - "github.com/tidepool-org/platform/migrations/back_37/utils" + "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" ) var _ = Describe("back-37", func() { diff --git a/migrations/back_37/back_37.go b/migrations/back_37/back_37.go deleted file mode 100644 index 4e0a2652bc..0000000000 --- a/migrations/back_37/back_37.go +++ /dev/null @@ -1,148 +0,0 @@ -package main - -import ( - "context" - "time" - - "github.com/urfave/cli" - "go.mongodb.org/mongo-driver/bson" - - "github.com/tidepool-org/platform/application" - "github.com/tidepool-org/platform/errors" - migrationMongo "github.com/tidepool-org/platform/migration/mongo" - "github.com/tidepool-org/platform/migrations/back_37/utils" - storeStructuredMongo "github.com/tidepool-org/platform/store/structured/mongo" -) - -func main() { - ctx := context.Background() - ctx, cancel := context.WithCancel(ctx) - defer cancel() - application.RunAndExit(NewMigration(ctx)) -} - -type Migration struct { - ctx context.Context - *migrationMongo.Migration - dataRepository *storeStructuredMongo.Repository -} - -func NewMigration(ctx context.Context) *Migration { - return &Migration{ - ctx: ctx, - Migration: migrationMongo.NewMigration(), - } -} - -func (m *Migration) Initialize(provider application.Provider) error { - if err := m.Migration.Initialize(provider); err != nil { - return err - } - - m.CLI().Usage = "BACK-37: Migrate all existing data to add required Platform deduplication hash fields" - m.CLI().Description = "BACK-37: To fully migrate devices from the `jellyfish` upload API to the `platform` upload API" - m.CLI().Authors = []cli.Author{ - { - Name: "J H BATE", - Email: "jamie@tidepool.org", - }, - } - - m.CLI().Action = func(ctx *cli.Context) error { - if !m.ParseContext(ctx) { - return nil - } - return m.execute() - } - - return nil -} - -func (m *Migration) execute() error { - m.Logger().Debug("Migrate jellyfish API data") - m.Logger().Debug("Creating data store") - - mongoConfig := m.NewMongoConfig() - mongoConfig.Database = "data" - mongoConfig.Timeout = 60 * time.Minute - dataStore, err := storeStructuredMongo.NewStore(mongoConfig) - if err != nil { - return errors.Wrap(err, "unable to create data store") - } - defer dataStore.Terminate(m.ctx) - - m.Logger().Debug("Creating data repository") - m.dataRepository = dataStore.GetRepository("deviceData") - m.Logger().Info("Migration of jellyfish documents has begun") - hashUpdatedCount, errorCount := m.migrateJellyfishDocuments() - m.Logger().Infof("Migrated %d jellyfish documents", hashUpdatedCount) - m.Logger().Infof("%d errors occurred", errorCount) - return nil -} - -func (m *Migration) migrateJellyfishDocuments() (int, int) { - logger := m.Logger() - logger.Debug("Finding jellyfish data") - var hashUpdatedCount, errorCount int - selector := bson.M{ - // jellyfish uses a generated _id that is not an mongo objectId - "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, - "_deduplicator": bson.M{"$exists": false}, - } - - var jellyfishResult bson.M - jellyfishDocCursor, err := m.dataRepository.Find(m.ctx, selector) - if err != nil { - logger.WithError(err).Error("Unable to find jellyfish data") - errorCount++ - return hashUpdatedCount, errorCount - } - defer jellyfishDocCursor.Close(m.ctx) - for jellyfishDocCursor.Next(m.ctx) { - err = jellyfishDocCursor.Decode(&jellyfishResult) - if err != nil { - logger.WithError(err).Error("Could not decode mongo doc") - errorCount++ - continue - } - if !m.DryRun() { - if updated, err := m.migrateDocument(jellyfishResult); err != nil { - logger.WithError(err).Errorf("Unable to migrate jellyfish document %s.", jellyfishResult["_id"]) - errorCount++ - continue - } else if updated { - hashUpdatedCount++ - } - } - } - if err := jellyfishDocCursor.Err(); err != nil { - logger.WithError(err).Error("Error while fetching data. Please re-run to complete the migration.") - errorCount++ - } - return hashUpdatedCount, errorCount -} - -func (m *Migration) migrateDocument(jfDatum bson.M) (bool, error) { - - datumID, err := utils.GetValidatedString(jfDatum, "_id") - if err != nil { - return false, err - } - - updates, err := utils.GetDatumUpdates(jfDatum) - if err != nil { - return false, err - } - - result, err := m.dataRepository.UpdateOne(m.ctx, bson.M{ - "_id": datumID, - "modifiedTime": jfDatum["modifiedTime"], - }, bson.M{ - "$set": updates, - }) - - if err != nil { - return false, err - } - return result.ModifiedCount == 1, nil -} From 6c2668ad9d5d76c5f45f2b0f624445ad813095db Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 30 Nov 2023 11:04:09 +1300 Subject: [PATCH 013/413] ordering of imports --- .../20231128_jellyfish_migration.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index cec3773e52..926f5e4068 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -6,6 +6,7 @@ import ( "math" "time" + "github.com/urfave/cli" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" @@ -13,7 +14,6 @@ import ( "github.com/tidepool-org/platform/application" migrationMongo "github.com/tidepool-org/platform/migration/mongo" "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" - "github.com/urfave/cli" ) type Config struct { From d296bd094178c58d53dd756fd4d2b844503022ed Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 6 Dec 2023 15:06:34 +1300 Subject: [PATCH 014/413] testing updates --- .../20231128_jellyfish_migration.go | 16 +- .../connect/connect.go | 215 ++++++++++++++++++ 2 files changed, 229 insertions(+), 2 deletions(-) create mode 100644 migrations/20231128_jellyfish_migration/connect/connect.go diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 926f5e4068..52f05252f6 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -2,6 +2,7 @@ package main import ( "context" + "errors" "fmt" "math" "time" @@ -44,6 +45,7 @@ type Migration struct { } const oplogName = "oplog.rs" +const DryRunFlag = "dry-run" func main() { ctx := context.Background() @@ -75,6 +77,12 @@ func (m *Migration) Initialize(provider application.Provider) error { }, } m.CLI().Flags = append(m.CLI().Flags, + + cli.BoolFlag{ + Name: fmt.Sprintf("%s,%s", DryRunFlag, "n"), + Usage: "dry run only; do not migrate", + }, + cli.Int64Flag{ Name: "batch-size", Usage: "number of records to read each time", @@ -121,7 +129,7 @@ func (m *Migration) Initialize(provider application.Provider) error { m.CLI().Action = func(ctx *cli.Context) error { if !m.ParseContext(ctx) { - return nil + return errors.New("could not parse context") } if err := m.prepare(); err != nil { return nil @@ -196,6 +204,10 @@ func (m *Migration) getOplogDuration() (time.Duration, error) { } +func calculateBatchSize(oplogSize int, oplogEntryBytes int, oplogMinWindow int, nopPercent int) int64 { + return int64(math.Floor(float64(oplogSize) / float64(oplogEntryBytes) / float64(oplogMinWindow) / (float64(nopPercent) / 7))) +} + func (m *Migration) setWriteBatchSize() error { if m.oplogC != nil { m.Logger().Debug("Getting oplog duration...") @@ -206,7 +218,7 @@ func (m *Migration) setWriteBatchSize() error { if err := m.oplogC.Database().RunCommand(m.ctx, bson.M{"collStats": oplogName}).Decode(&metaData); err != nil { return err } - writeBatchSize := int64(metaData.MaxSize / m.config.expectedOplogEntrySize / m.config.minOplogWindow / (m.config.nopPercent / 7)) + writeBatchSize := calculateBatchSize(metaData.MaxSize, m.config.expectedOplogEntrySize, m.config.minOplogWindow, m.config.nopPercent) m.writeBatchSize = &writeBatchSize return nil } diff --git a/migrations/20231128_jellyfish_migration/connect/connect.go b/migrations/20231128_jellyfish_migration/connect/connect.go new file mode 100644 index 0000000000..c302b17907 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/connect/connect.go @@ -0,0 +1,215 @@ +package main + +import ( + "context" + "fmt" + "log" + "math" + "os" + + "github.com/urfave/cli" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + +type Config struct { + uri string + minOplogWindow int + // these values are used to determine writes batches, first dividing the oplog's size with the desired duration and + // expected entry size, then adding a divisor to account for NOP overshoot in the oplog + expectedOplogEntrySize int + // how much of the oplog is NOP, this adjusts the batch to account for an oplog that is very change sensitive + // must be > 0 + // prod 0.6 + // idle 100 + nopPercent int + // minimum free disk space percent + minFreePercent int + readBatchSize int64 +} + +type Migration struct { + cli *cli.App + ctx context.Context + config *Config + client *mongo.Client + oplogC *mongo.Collection + deviceDataC *mongo.Collection + writeBatchSize *int64 + updates []mongo.WriteModel +} + +const oplogName = "oplog.rs" + +func main() { + ctx := context.Background() + ctx, cancel := context.WithCancel(ctx) + defer cancel() + migration := NewMigration(ctx) + migration.RunAndExit() +} + +func NewMigration(ctx context.Context) *Migration { + return &Migration{ + cli: cli.NewApp(), + ctx: ctx, + config: &Config{}, + updates: []mongo.WriteModel{}, + } +} + +func (m *Migration) RunAndExit() { + if err := m.Initialize(); err != nil { + os.Exit(1) + } + + m.CLI().Action = func(ctx *cli.Context) error { + log.Println("before prepare") + if err := m.prepare(); err != nil { + return err + } + return nil + } + + if err := m.CLI().Run(os.Args); err != nil { + os.Exit(1) + } + + os.Exit(0) +} + +func (m *Migration) CLI() *cli.App { + return m.cli +} + +func (m *Migration) Initialize() error { + + log.Println("Initialize...") + + m.CLI().Usage = "BACK-37: Migrate all existing data to add required Platform deduplication hash fields" + m.CLI().Description = "BACK-37: To fully migrate devices from the `jellyfish` upload API to the `platform` upload API" + m.CLI().Authors = []cli.Author{ + { + Name: "J H BATE", + Email: "jamie@tidepool.org", + }, + } + m.CLI().Flags = append(m.CLI().Flags, + cli.Int64Flag{ + Name: "batch-size", + Usage: "number of records to read each time", + Destination: &m.config.readBatchSize, + Value: 3000, + Required: false, + }, + cli.IntFlag{ + Name: "min-free-percent", + Usage: "minimum free disk space percent", + Destination: &m.config.minFreePercent, + Value: 10, + Required: false, + }, + cli.IntFlag{ + Name: "nop-percent", + Usage: "how much of the oplog is NOP", + Destination: &m.config.nopPercent, + Value: 100, + Required: false, + }, + cli.IntFlag{ + Name: "oplog-entry-size", + Usage: "minimum free disk space percent", + Destination: &m.config.expectedOplogEntrySize, + Value: 420, + Required: false, + }, + cli.IntFlag{ + Name: "oplog-window", + Usage: "minimum oplog window in seconds", + Destination: &m.config.minOplogWindow, + Value: 28800, // 8hrs + Required: false, + }, + cli.StringFlag{ + Name: "uri", + Usage: "mongo connection URI", + Destination: &m.config.uri, + Value: "mongodb://localhost:27017", + Required: false, + }, + ) + return nil +} + +func (m *Migration) prepare() error { + log.Println("running prepare ...") + var err error + m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(m.config.uri)) + if err != nil { + return fmt.Errorf("unable to connect to MongoDB: %w", err) + } + defer m.client.Disconnect(m.ctx) + + m.oplogC = m.client.Database("local").Collection(oplogName) + m.deviceDataC = m.client.Database("data").Collection("deviceData") + + if err := m.checkFreeSpace(); err != nil { + return err + } + + err = m.setWriteBatchSize() + if err != nil { + return err + } + return nil +} + +func (m *Migration) setWriteBatchSize() error { + if m.oplogC != nil { + log.Println("Getting Write Batch Size...") + type MongoMetaData struct { + MaxSize int `json:"maxSize"` + } + var metaData MongoMetaData + if err := m.oplogC.Database().RunCommand(m.ctx, bson.M{"collStats": oplogName}).Decode(&metaData); err != nil { + return err + } + log.Printf("oplogSize... %v", metaData.MaxSize) + writeBatchSize := int64(math.Floor( + float64(metaData.MaxSize) / + float64(m.config.expectedOplogEntrySize) / + float64(m.config.minOplogWindow) / + (float64(m.config.nopPercent) / float64(7)))) + log.Printf("writeBatchSize... %v", writeBatchSize) + m.writeBatchSize = &writeBatchSize + return nil + } + var writeBatchSize = int64(30000) + log.Printf("MongoDB is not clustered, removing write batch limit, setting to %d documents.", writeBatchSize) + m.writeBatchSize = &writeBatchSize + return nil +} + +func (m *Migration) checkFreeSpace() error { + type MongoMetaData struct { + FsTotalSize int `json:"fsTotalSize"` + FsUsedSize int `json:"fsUsedSize"` + } + var metaData MongoMetaData + log.Println("Getting DB free space...") + err := m.deviceDataC.Database().RunCommand(m.ctx, bson.M{"dbStats": 1}).Decode(&metaData) + if err != nil { + return err + } + + log.Printf("Stats ... %v ", metaData) + bytesFree := metaData.FsTotalSize - metaData.FsUsedSize + percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) + log.Printf("DB disk currently has %d%% (%d) free.", percentFree*100, bytesFree) + + if percentFree > m.config.minFreePercent { + return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) + } + return nil +} From c5a90136d16c5e78de0283b93b662ec86566f14b Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 7 Dec 2023 10:03:24 +1300 Subject: [PATCH 015/413] test updates --- .../20231128_jellyfish_migration.go | 116 ++++++++++++------ .../connect/connect.go | 10 +- 2 files changed, 82 insertions(+), 44 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 52f05252f6..1219fdaf81 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -2,9 +2,10 @@ package main import ( "context" - "errors" "fmt" + "log" "math" + "os" "time" "github.com/urfave/cli" @@ -12,8 +13,6 @@ import ( "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" - "github.com/tidepool-org/platform/application" - migrationMongo "github.com/tidepool-org/platform/migration/mongo" "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" ) @@ -35,8 +34,9 @@ type Config struct { type Migration struct { ctx context.Context + cli *cli.App config *Config - *migrationMongo.Migration + //*migrationMongo.Migration client *mongo.Client oplogC *mongo.Collection deviceDataC *mongo.Collection @@ -51,23 +51,49 @@ func main() { ctx := context.Background() ctx, cancel := context.WithCancel(ctx) defer cancel() - application.RunAndExit(NewMigration(ctx)) + //application.RunAndExit(NewMigration(ctx)) + + migration := NewMigration(ctx) + migration.RunAndExit() } func NewMigration(ctx context.Context) *Migration { return &Migration{ - ctx: ctx, - Migration: migrationMongo.NewMigration(), - config: &Config{}, - updates: []mongo.WriteModel{}, + ctx: ctx, + cli: cli.NewApp(), + //Migration: migrationMongo.NewMigration(), + config: &Config{}, + updates: []mongo.WriteModel{}, } } -func (m *Migration) Initialize(provider application.Provider) error { - if err := m.Migration.Initialize(provider); err != nil { - return err +func (m *Migration) RunAndExit() { + if err := m.Initialize(); err != nil { + os.Exit(1) + } + + m.CLI().Action = func(ctx *cli.Context) error { + log.Printf("config %#v", m.config) + if err := m.prepare(); err != nil { + log.Printf("error %s", err) + return err + } + return nil + } + + if err := m.CLI().Run(os.Args); err != nil { + os.Exit(1) } + os.Exit(0) +} + +func (m *Migration) Initialize() error { + log.Println("init") + // if err := m.Migration.Initialize(provider); err != nil { + // return err + // } + m.CLI().Usage = "BACK-37: Migrate all existing data to add required Platform deduplication hash fields" m.CLI().Description = "BACK-37: To fully migrate devices from the `jellyfish` upload API to the `platform` upload API" m.CLI().Authors = []cli.Author{ @@ -127,19 +153,24 @@ func (m *Migration) Initialize(provider application.Provider) error { }, ) - m.CLI().Action = func(ctx *cli.Context) error { - if !m.ParseContext(ctx) { - return errors.New("could not parse context") - } - if err := m.prepare(); err != nil { - return nil - } - return m.execute() - } + // m.CLI().Action = func(ctx *cli.Context) error { + // // if !m.ParseContext(ctx) { + // // return errors.New("could not parse context") + // // } + // if err := m.prepare(); err != nil { + // return nil + // } + // return m.execute() + // } return nil } +func (m *Migration) CLI() *cli.App { + return m.cli +} + func (m *Migration) prepare() error { + log.Println("prepare") var err error m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(m.config.uri)) if err != nil { @@ -166,11 +197,11 @@ func (m *Migration) execute() error { for m.fetchAndUpdateBatch() { updatedCount, err := m.writeBatchUpdates() if err != nil { - m.Logger().WithError(err).Error("failed writing batch") + log.Printf("failed writing batch %s", err) return err } totalMigrated = totalMigrated + updatedCount - m.Logger().Debugf("migrated %d for a total of %d migrated items", updatedCount, totalMigrated) + log.Printf("migrated %d for a total of %d migrated items", updatedCount, totalMigrated) } return nil } @@ -195,10 +226,10 @@ func (m *Migration) getOplogDuration() (time.Duration, error) { return 0, err } oplogDuration := oldest.Wall.Sub(oldest.Wall) - m.Logger().Debugf("oplog duration is currently: %v\n", oplogDuration) + log.Printf("oplog duration is currently: %v\n", oplogDuration) return oplogDuration, nil } - m.Logger().Debug("Not clustered, not retrieving oplog duration.") + log.Println("Not clustered, not retrieving oplog duration.") oplogDuration := time.Duration(m.config.minOplogWindow+1) * time.Second return oplogDuration, nil @@ -209,8 +240,9 @@ func calculateBatchSize(oplogSize int, oplogEntryBytes int, oplogMinWindow int, } func (m *Migration) setWriteBatchSize() error { + log.Println("set write batch size...") if m.oplogC != nil { - m.Logger().Debug("Getting oplog duration...") + log.Println("Getting oplog stats...") type MongoMetaData struct { MaxSize int `json:"maxSize"` } @@ -218,39 +250,43 @@ func (m *Migration) setWriteBatchSize() error { if err := m.oplogC.Database().RunCommand(m.ctx, bson.M{"collStats": oplogName}).Decode(&metaData); err != nil { return err } + log.Printf("oplog maxSize: %d", metaData.MaxSize) writeBatchSize := calculateBatchSize(metaData.MaxSize, m.config.expectedOplogEntrySize, m.config.minOplogWindow, m.config.nopPercent) m.writeBatchSize = &writeBatchSize + log.Printf("writeBatchSize: %d", writeBatchSize) return nil } var writeBatchSize = int64(30000) - m.Logger().Debugf("MongoDB is not clustered, removing write batch limit, setting to %d documents.", writeBatchSize) + log.Printf("MongoDB is not clustered, removing write batch limit, setting to %d documents.", writeBatchSize) m.writeBatchSize = &writeBatchSize return nil } func (m *Migration) checkFreeSpace() error { + log.Println("check free space...") type MongoMetaData struct { FsTotalSize int `json:"fsTotalSize"` FsUsedSize int `json:"fsUsedSize"` } var metaData MongoMetaData - m.Logger().Debug("Getting DB free space...") + log.Println("Getting DB free space...") err := m.deviceDataC.Database().RunCommand(m.ctx, bson.M{"dbStats": 1}).Decode(&metaData) if err != nil { return err } + log.Printf("DB free space: %v", metaData) bytesFree := metaData.FsTotalSize - metaData.FsUsedSize percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) - m.Logger().Debugf("DB disk currently has %d%% (%d) free.", percentFree*100, bytesFree) + log.Printf("DB disk currently has %d%% (%d) free.", percentFree*100, bytesFree) - if percentFree > m.config.minFreePercent { + if m.config.minFreePercent > percentFree { return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) } return nil } func (m *Migration) getWaitTime() (float64, error) { - m.Logger().Debug("Loading DB replication status...") + log.Println("Loading DB replication status...") type Member struct { Name string `json:"name"` @@ -265,11 +301,11 @@ func (m *Migration) getWaitTime() (float64, error) { var metaData MongoMetaData m.client.Database("admin").RunCommand(m.ctx, bson.M{"replSetGetStatus": 1}).Decode(&metaData) - m.Logger().Debug("DB replication status loaded.") + log.Println("DB replication status loaded.") for _, member := range metaData.Members { if member.State < 1 || member.State > 2 || member.Health != 1 || member.Uptime < 120 { - m.Logger().Debugf("DB member %s down or not ready.", member.Name) + log.Printf("DB member %s down or not ready.", member.Name) return 240, nil } } @@ -280,7 +316,7 @@ func (m *Migration) getWaitTime() (float64, error) { } if oplogDuration.Seconds() < float64(m.config.minOplogWindow) { minOplogWindowTime := time.Duration(m.config.minOplogWindow) * time.Second - m.Logger().Debugf("DB OPLOG shorter than requested duration of %s, currently %s.", minOplogWindowTime, oplogDuration) + log.Printf("DB OPLOG shorter than requested duration of %s, currently %s.", minOplogWindowTime, oplogDuration) waitTime := float64(m.config.minOplogWindow) - oplogDuration.Seconds() waitTime *= 1.15 if waitTime < 600 { @@ -300,9 +336,9 @@ func (m *Migration) blockUntilDBReady() error { for waitTime > 0 { totalWait += waitTime if totalWait > 1800 { - m.Logger().Debugf("Long total wait of %s, possibly high load, or sustained DB outage. If neither, adjust NOP_PERCENT to reduce overshoot.", time.Duration(totalWait)*time.Second) + log.Printf("Long total wait of %s, possibly high load, or sustained DB outage. If neither, adjust NOP_PERCENT to reduce overshoot.", time.Duration(totalWait)*time.Second) } - m.Logger().Debugf("Sleeping for %d", time.Duration(waitTime)*time.Second) + log.Printf("Sleeping for %d", time.Duration(waitTime)*time.Second) time.Sleep(time.Duration(waitTime) * time.Second) waitTime, err = m.getWaitTime() if err != nil { @@ -324,7 +360,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { &options.FindOptions{Limit: &m.config.readBatchSize}, ) if err != nil { - m.Logger().WithError(err).Error("failed to select data") + log.Printf("failed to select data: %s", err) return false } @@ -334,19 +370,19 @@ func (m *Migration) fetchAndUpdateBatch() bool { for dDataCursor.Next(m.ctx) { err = dDataCursor.Decode(&dDataResult) if err != nil { - m.Logger().WithError(err).Error("failed decoding data") + log.Printf("failed decoding data: %s", err) return false } datumID, err := utils.GetValidatedString(dDataResult, "_id") if err != nil { - m.Logger().WithError(err).Error("failed getting dutum _id") + log.Printf("failed getting dutum _id: %s", err) return false } updates, err := utils.GetDatumUpdates(dDataResult) if err != nil { - m.Logger().WithError(err).Error("failed getting datum updates") + log.Printf("failed getting datum updates: %s", err) return false } diff --git a/migrations/20231128_jellyfish_migration/connect/connect.go b/migrations/20231128_jellyfish_migration/connect/connect.go index c302b17907..754d81b71c 100644 --- a/migrations/20231128_jellyfish_migration/connect/connect.go +++ b/migrations/20231128_jellyfish_migration/connect/connect.go @@ -67,6 +67,7 @@ func (m *Migration) RunAndExit() { m.CLI().Action = func(ctx *cli.Context) error { log.Println("before prepare") if err := m.prepare(); err != nil { + log.Printf("error %s", err) return err } return nil @@ -143,7 +144,7 @@ func (m *Migration) Initialize() error { } func (m *Migration) prepare() error { - log.Println("running prepare ...") + log.Println("Prepare ...") var err error m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(m.config.uri)) if err != nil { @@ -192,6 +193,7 @@ func (m *Migration) setWriteBatchSize() error { } func (m *Migration) checkFreeSpace() error { + log.Println("check free space...") type MongoMetaData struct { FsTotalSize int `json:"fsTotalSize"` FsUsedSize int `json:"fsUsedSize"` @@ -200,15 +202,15 @@ func (m *Migration) checkFreeSpace() error { log.Println("Getting DB free space...") err := m.deviceDataC.Database().RunCommand(m.ctx, bson.M{"dbStats": 1}).Decode(&metaData) if err != nil { + return err } - - log.Printf("Stats ... %v ", metaData) + log.Printf("DB free space: %v", metaData) bytesFree := metaData.FsTotalSize - metaData.FsUsedSize percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) log.Printf("DB disk currently has %d%% (%d) free.", percentFree*100, bytesFree) - if percentFree > m.config.minFreePercent { + if m.config.minFreePercent > percentFree { return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) } return nil From 2cdc4c648732342925d7cff512688c7660093818 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 7 Dec 2023 14:28:26 +1300 Subject: [PATCH 016/413] test with grouping based on specific user --- .../20231128_jellyfish_migration.go | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 1219fdaf81..a5c9ffd3e8 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -55,6 +55,7 @@ func main() { migration := NewMigration(ctx) migration.RunAndExit() + log.Println("finished migration") } func NewMigration(ctx context.Context) *Migration { @@ -75,17 +76,20 @@ func (m *Migration) RunAndExit() { m.CLI().Action = func(ctx *cli.Context) error { log.Printf("config %#v", m.config) if err := m.prepare(); err != nil { - log.Printf("error %s", err) + log.Printf("prepare failed: %s", err) return err } + if err := m.execute(); err != nil { + log.Printf("execute failed: %s", err) + return err + } + log.Println("finished prepare") return nil } if err := m.CLI().Run(os.Args); err != nil { os.Exit(1) } - - os.Exit(0) } func (m *Migration) Initialize() error { @@ -113,7 +117,7 @@ func (m *Migration) Initialize() error { Name: "batch-size", Usage: "number of records to read each time", Destination: &m.config.readBatchSize, - Value: 3000, + Value: 30, Required: false, }, cli.IntFlag{ @@ -277,7 +281,7 @@ func (m *Migration) checkFreeSpace() error { log.Printf("DB free space: %v", metaData) bytesFree := metaData.FsTotalSize - metaData.FsUsedSize percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) - log.Printf("DB disk currently has %d%% (%d) free.", percentFree*100, bytesFree) + log.Printf("DB disk currently has %d%% (%d bytes) free.", percentFree, bytesFree) if m.config.minFreePercent > percentFree { return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) @@ -304,6 +308,7 @@ func (m *Migration) getWaitTime() (float64, error) { log.Println("DB replication status loaded.") for _, member := range metaData.Members { + log.Printf("member %#v ", member) if member.State < 1 || member.State > 2 || member.Health != 1 || member.Uptime < 120 { log.Printf("DB member %s down or not ready.", member.Name) return 240, nil @@ -314,6 +319,7 @@ func (m *Migration) getWaitTime() (float64, error) { if err != nil { return 0, err } + log.Printf("oplogDuration %v ", oplogDuration) if oplogDuration.Seconds() < float64(m.config.minOplogWindow) { minOplogWindowTime := time.Duration(m.config.minOplogWindow) * time.Second log.Printf("DB OPLOG shorter than requested duration of %s, currently %s.", minOplogWindowTime, oplogDuration) @@ -328,6 +334,7 @@ func (m *Migration) getWaitTime() (float64, error) { } func (m *Migration) blockUntilDBReady() error { + log.Println("blocking...") waitTime, err := m.getWaitTime() if err != nil { return err @@ -342,6 +349,7 @@ func (m *Migration) blockUntilDBReady() error { time.Sleep(time.Duration(waitTime) * time.Second) waitTime, err = m.getWaitTime() if err != nil { + log.Printf("failed getting wait time %d", time.Duration(waitTime)*time.Second) return err } } @@ -353,6 +361,8 @@ func (m *Migration) fetchAndUpdateBatch() bool { // jellyfish uses a generated _id that is not an mongo objectId "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, "_deduplicator": bson.M{"$exists": false}, + // testing based on _userId for jamie+qa3_1@tidepool.org + "_userId": "5e8cac61-6bef-4728-b490-c1d82087ed9c", } m.updates = []mongo.WriteModel{} @@ -419,11 +429,16 @@ func (m *Migration) writeBatchUpdates() (int, error) { if err := m.checkFreeSpace(); err != nil { return updateCount, err } - results, err := m.deviceDataC.BulkWrite(m.ctx, batch) - if err != nil { - return updateCount, err - } - updateCount = updateCount + int(results.ModifiedCount) + log.Printf("updates to write %d", len(batch)) + + updateCount += len(batch) + log.Printf("updates applied so far %d", updateCount) + // results, err := m.deviceDataC.BulkWrite(m.ctx, batch) + // if err != nil { + // return updateCount, err + // } + // updateCount = updateCount + int(results.ModifiedCount) } + log.Printf("applied %d updates", updateCount) return updateCount, nil } From 87363602350ee71457e9ead328a69ce151000daf Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 7 Dec 2023 15:03:25 +1300 Subject: [PATCH 017/413] use client connection --- .../20231128_jellyfish_migration.go | 140 ++++++++++-------- 1 file changed, 76 insertions(+), 64 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index a5c9ffd3e8..2811f0e0e9 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -2,6 +2,7 @@ package main import ( "context" + "errors" "fmt" "log" "math" @@ -38,8 +39,6 @@ type Migration struct { config *Config //*migrationMongo.Migration client *mongo.Client - oplogC *mongo.Collection - deviceDataC *mongo.Collection writeBatchSize *int64 updates []mongo.WriteModel } @@ -74,6 +73,14 @@ func (m *Migration) RunAndExit() { } m.CLI().Action = func(ctx *cli.Context) error { + log.Println("prepare") + var err error + m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(m.config.uri)) + if err != nil { + return fmt.Errorf("unable to connect to MongoDB: %w", err) + } + defer m.client.Disconnect(m.ctx) + log.Printf("config %#v", m.config) if err := m.prepare(); err != nil { log.Printf("prepare failed: %s", err) @@ -173,30 +180,25 @@ func (m *Migration) CLI() *cli.App { return m.cli } -func (m *Migration) prepare() error { - log.Println("prepare") - var err error - m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(m.config.uri)) - if err != nil { - return fmt.Errorf("unable to connect to MongoDB: %w", err) - } - defer m.client.Disconnect(m.ctx) - - m.oplogC = m.client.Database("local").Collection(oplogName) - m.deviceDataC = m.client.Database("data").Collection("deviceData") +func (m *Migration) getDataCollection() *mongo.Collection { + return m.client.Database("data").Collection("deviceData") +} +func (m *Migration) getOplogCollection() *mongo.Collection { + return m.client.Database("local").Collection(oplogName) +} +func (m *Migration) prepare() error { if err := m.checkFreeSpace(); err != nil { return err } - - err = m.setWriteBatchSize() - if err != nil { + if err := m.setWriteBatchSize(); err != nil { return err } return nil } func (m *Migration) execute() error { + log.Println("about to run execute") totalMigrated := 0 for m.fetchAndUpdateBatch() { updatedCount, err := m.writeBatchUpdates() @@ -214,16 +216,16 @@ func (m *Migration) getOplogDuration() (time.Duration, error) { type MongoMetaData struct { Wall time.Time `json:"wall"` } - if m.oplogC != nil { + if oplogC := m.getOplogCollection(); oplogC != nil { var oldest MongoMetaData - if err := m.oplogC.FindOne( + if err := oplogC.FindOne( m.ctx, bson.M{}, options.FindOne().SetSort("$natural"), options.FindOne().SetProjection(bson.M{"wall": 1})).Decode(&oldest); err != nil { return 0, err } var newest MongoMetaData - if err := m.oplogC.FindOne(m.ctx, + if err := oplogC.FindOne(m.ctx, bson.M{}, options.FindOne().SetSort("-$natural"), options.FindOne().SetProjection(bson.M{"wall": 1})).Decode(&newest); err != nil { @@ -245,13 +247,13 @@ func calculateBatchSize(oplogSize int, oplogEntryBytes int, oplogMinWindow int, func (m *Migration) setWriteBatchSize() error { log.Println("set write batch size...") - if m.oplogC != nil { + if oplogC := m.getOplogCollection(); oplogC != nil { log.Println("Getting oplog stats...") type MongoMetaData struct { MaxSize int `json:"maxSize"` } var metaData MongoMetaData - if err := m.oplogC.Database().RunCommand(m.ctx, bson.M{"collStats": oplogName}).Decode(&metaData); err != nil { + if err := oplogC.Database().RunCommand(m.ctx, bson.M{"collStats": oplogName}).Decode(&metaData); err != nil { return err } log.Printf("oplog maxSize: %d", metaData.MaxSize) @@ -274,19 +276,24 @@ func (m *Migration) checkFreeSpace() error { } var metaData MongoMetaData log.Println("Getting DB free space...") - err := m.deviceDataC.Database().RunCommand(m.ctx, bson.M{"dbStats": 1}).Decode(&metaData) - if err != nil { - return err - } - log.Printf("DB free space: %v", metaData) - bytesFree := metaData.FsTotalSize - metaData.FsUsedSize - percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) - log.Printf("DB disk currently has %d%% (%d bytes) free.", percentFree, bytesFree) - if m.config.minFreePercent > percentFree { - return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) + if dataC := m.getDataCollection(); dataC != nil { + + err := dataC.Database().RunCommand(m.ctx, bson.M{"dbStats": 1}).Decode(&metaData) + if err != nil { + return err + } + log.Printf("DB free space: %v", metaData) + bytesFree := metaData.FsTotalSize - metaData.FsUsedSize + percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) + log.Printf("DB disk currently has %d%% (%d bytes) free.", percentFree, bytesFree) + + if m.config.minFreePercent > percentFree { + return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) + } + return nil } - return nil + return errors.New("could not get deviceData database") } func (m *Migration) getWaitTime() (float64, error) { @@ -357,6 +364,7 @@ func (m *Migration) blockUntilDBReady() error { } func (m *Migration) fetchAndUpdateBatch() bool { + selector := bson.M{ // jellyfish uses a generated _id that is not an mongo objectId "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, @@ -366,45 +374,49 @@ func (m *Migration) fetchAndUpdateBatch() bool { } m.updates = []mongo.WriteModel{} - dDataCursor, err := m.deviceDataC.Find(m.ctx, selector, - &options.FindOptions{Limit: &m.config.readBatchSize}, - ) - if err != nil { - log.Printf("failed to select data: %s", err) - return false - } - - var dDataResult bson.M - - defer dDataCursor.Close(m.ctx) - for dDataCursor.Next(m.ctx) { - err = dDataCursor.Decode(&dDataResult) + if dataC := m.getDataCollection(); dataC != nil { + dDataCursor, err := dataC.Find(m.ctx, selector, + &options.FindOptions{Limit: &m.config.readBatchSize}, + ) if err != nil { - log.Printf("failed decoding data: %s", err) + log.Printf("failed to select data: %s", err) return false } - datumID, err := utils.GetValidatedString(dDataResult, "_id") - if err != nil { - log.Printf("failed getting dutum _id: %s", err) - return false - } + var dDataResult bson.M - updates, err := utils.GetDatumUpdates(dDataResult) - if err != nil { - log.Printf("failed getting datum updates: %s", err) - return false - } + defer dDataCursor.Close(m.ctx) + for dDataCursor.Next(m.ctx) { + err = dDataCursor.Decode(&dDataResult) + if err != nil { + log.Printf("failed decoding data: %s", err) + return false + } - m.updates = append(m.updates, mongo.NewUpdateOneModel().SetFilter( - bson.M{ - "_id": datumID, - "modifiedTime": dDataResult["modifiedTime"], - }).SetUpdate(bson.M{ - "$set": updates, - })) + datumID, err := utils.GetValidatedString(dDataResult, "_id") + if err != nil { + log.Printf("failed getting dutum _id: %s", err) + return false + } + + updates, err := utils.GetDatumUpdates(dDataResult) + if err != nil { + log.Printf("failed getting datum updates: %s", err) + return false + } + + m.updates = append(m.updates, mongo.NewUpdateOneModel().SetFilter( + bson.M{ + "_id": datumID, + "modifiedTime": dDataResult["modifiedTime"], + }).SetUpdate(bson.M{ + "$set": updates, + })) + } + return len(m.updates) > 0 } - return len(m.updates) > 0 + log.Println("get deviceData collection ") + return false } func (m *Migration) writeBatchUpdates() (int, error) { From 71c49fa9848938422c9cdd4ca8b44e3131f862c4 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 7 Dec 2023 16:30:14 +1300 Subject: [PATCH 018/413] time string --- migrations/20231128_jellyfish_migration/utils/utils.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index c12e92c4c0..0307379a73 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -40,6 +40,9 @@ func getValidatedTime(bsonData bson.M, fieldName string) (time.Time, error) { if valRaw, ok := bsonData[fieldName]; !ok { return time.Time{}, errors.Newf("%s is missing", fieldName) } else if val, ok := valRaw.(time.Time); !ok { + if tStr, ok := valRaw.(string); ok { + return time.Parse(time.RFC3339, tStr) + } return time.Time{}, errors.Newf("%s is not of expected type", fieldName) } else if val.IsZero() { return time.Time{}, errors.Newf("%s is empty", fieldName) From 80ed360f26425f012bcc44f8568728c83926ae85 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 7 Dec 2023 16:42:31 +1300 Subject: [PATCH 019/413] time fix --- .../utils/utils.go | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 0307379a73..419539ae2e 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -2,6 +2,7 @@ package utils import ( "fmt" + "log" "slices" "strconv" "strings" @@ -36,19 +37,18 @@ func GetValidatedString(bsonData bson.M, fieldName string) (string, error) { } } -func getValidatedTime(bsonData bson.M, fieldName string) (time.Time, error) { +func getValidatedTime(bsonData bson.M, fieldName string) (string, error) { if valRaw, ok := bsonData[fieldName]; !ok { - return time.Time{}, errors.Newf("%s is missing", fieldName) - } else if val, ok := valRaw.(time.Time); !ok { - if tStr, ok := valRaw.(string); ok { - return time.Parse(time.RFC3339, tStr) + return "", errors.Newf("%s is missing", fieldName) + } else if val, ok := valRaw.(string); !ok { + t, err := time.Parse(types.TimeFormat, val) + if err != nil { + return "", err } - return time.Time{}, errors.Newf("%s is not of expected type", fieldName) - } else if val.IsZero() { - return time.Time{}, errors.Newf("%s is empty", fieldName) - } else { - return val, nil + return t.Format(types.TimeFormat), nil } + log.Printf("invalid data %#v", bsonData) + return "", errors.Newf("%s is missing", fieldName) } func datumHash(bsonData bson.M) (string, error) { @@ -66,10 +66,11 @@ func datumHash(bsonData bson.M) (string, error) { if datumTime, err := getValidatedTime(bsonData, "time"); err != nil { return "", err } else { - identityFields = append(identityFields, datumTime.Format(types.TimeFormat)) + identityFields = append(identityFields, datumTime) } datumType, err := GetValidatedString(bsonData, "type") if err != nil { + log.Printf("invalid data: %#v", bsonData) return "", err } identityFields = append(identityFields, datumType) From e46a5afe55e4da8209cf53f831c57db798eda2bb Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 7 Dec 2023 16:52:52 +1300 Subject: [PATCH 020/413] error detail --- migrations/20231128_jellyfish_migration/utils/utils.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 419539ae2e..1b3376c7d2 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -52,25 +52,29 @@ func getValidatedTime(bsonData bson.M, fieldName string) (string, error) { } func datumHash(bsonData bson.M) (string, error) { + identityFields := []string{} if datumUserID, err := GetValidatedString(bsonData, "_userId"); err != nil { + log.Printf("invalid data _userId: %#v", bsonData) return "", err } else { identityFields = append(identityFields, datumUserID) } if deviceID, err := GetValidatedString(bsonData, "deviceId"); err != nil { + log.Printf("invalid data deviceId: %#v", bsonData) return "", err } else { identityFields = append(identityFields, deviceID) } if datumTime, err := getValidatedTime(bsonData, "time"); err != nil { + log.Printf("invalid data time: %#v", bsonData) return "", err } else { identityFields = append(identityFields, datumTime) } datumType, err := GetValidatedString(bsonData, "type") if err != nil { - log.Printf("invalid data: %#v", bsonData) + log.Printf("invalid data type: %#v", bsonData) return "", err } identityFields = append(identityFields, datumType) From 5b38ecced5a9c910be97b32f7f910a5c14709d3c Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 7 Dec 2023 16:59:55 +1300 Subject: [PATCH 021/413] disconnect on fail --- .../20231128_jellyfish_migration.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 2811f0e0e9..7f637eb9b2 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -73,7 +73,7 @@ func (m *Migration) RunAndExit() { } m.CLI().Action = func(ctx *cli.Context) error { - log.Println("prepare") + log.Println("running") var err error m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(m.config.uri)) if err != nil { @@ -95,6 +95,10 @@ func (m *Migration) RunAndExit() { } if err := m.CLI().Run(os.Args); err != nil { + if m.client != nil { + m.client.Disconnect(m.ctx) + } + os.Exit(1) } } From 1ff02a981d0257cad604555e1beb878cd66757d3 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 7 Dec 2023 19:38:02 +1300 Subject: [PATCH 022/413] time from millis --- .../20231128_jellyfish_migration.go | 1 - migrations/20231128_jellyfish_migration/utils/utils.go | 8 +++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 7f637eb9b2..4f90051f7a 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -98,7 +98,6 @@ func (m *Migration) RunAndExit() { if m.client != nil { m.client.Disconnect(m.ctx) } - os.Exit(1) } } diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 1b3376c7d2..ec4e7bbb5c 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -40,12 +40,10 @@ func GetValidatedString(bsonData bson.M, fieldName string) (string, error) { func getValidatedTime(bsonData bson.M, fieldName string) (string, error) { if valRaw, ok := bsonData[fieldName]; !ok { return "", errors.Newf("%s is missing", fieldName) - } else if val, ok := valRaw.(string); !ok { - t, err := time.Parse(types.TimeFormat, val) - if err != nil { - return "", err + } else if ms, ok := valRaw.(int64); !ok { + if t := time.Unix(0, ms*int64(time.Millisecond)); !t.IsZero() { + return t.Format(types.TimeFormat), nil } - return t.Format(types.TimeFormat), nil } log.Printf("invalid data %#v", bsonData) return "", errors.Newf("%s is missing", fieldName) From 9ddac0fc81b77d2e777db4fa108a97835ff703cb Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 12 Dec 2023 09:40:16 +1300 Subject: [PATCH 023/413] debug --- .../20231128_jellyfish_migration.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 4f90051f7a..a08750b1c9 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -206,7 +206,7 @@ func (m *Migration) execute() error { for m.fetchAndUpdateBatch() { updatedCount, err := m.writeBatchUpdates() if err != nil { - log.Printf("failed writing batch %s", err) + log.Printf("failed writing batch: %s", err) return err } totalMigrated = totalMigrated + updatedCount @@ -315,10 +315,9 @@ func (m *Migration) getWaitTime() (float64, error) { var metaData MongoMetaData m.client.Database("admin").RunCommand(m.ctx, bson.M{"replSetGetStatus": 1}).Decode(&metaData) - log.Println("DB replication status loaded.") + log.Printf("DB replication status loaded. %#v", metaData) for _, member := range metaData.Members { - log.Printf("member %#v ", member) if member.State < 1 || member.State > 2 || member.Health != 1 || member.Uptime < 120 { log.Printf("DB member %s down or not ready.", member.Name) return 240, nil @@ -427,7 +426,6 @@ func (m *Migration) writeBatchUpdates() (int, error) { batches := [][]mongo.WriteModel{} for i := 0; i < len(m.updates); i += chunkSize { end := i + chunkSize - if end > len(m.updates) { end = len(m.updates) } @@ -435,13 +433,15 @@ func (m *Migration) writeBatchUpdates() (int, error) { } return batches } - updateCount := 0 + log.Printf("write batch size %d", *m.writeBatchSize) for _, batch := range getBatches(int(*m.writeBatchSize)) { if err := m.blockUntilDBReady(); err != nil { + log.Printf("writeBatchUpdates-blocking error: %s", err) return updateCount, err } if err := m.checkFreeSpace(); err != nil { + log.Printf("writeBatchUpdates-freespace error: %s", err) return updateCount, err } log.Printf("updates to write %d", len(batch)) From 21b40f876284e9ed44fc8a31c95f3d4003d107d9 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 12 Dec 2023 11:44:28 +1300 Subject: [PATCH 024/413] rework oplog duration calc --- .../20231128_jellyfish_migration.go | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index a08750b1c9..49b67c985d 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -217,24 +217,31 @@ func (m *Migration) execute() error { func (m *Migration) getOplogDuration() (time.Duration, error) { type MongoMetaData struct { - Wall time.Time `json:"wall"` + Wall int64 `json:"wall"` } + log.Println("checking oplog duration ") if oplogC := m.getOplogCollection(); oplogC != nil { var oldest MongoMetaData + if err := oplogC.FindOne( - m.ctx, bson.M{}, - options.FindOne().SetSort("$natural"), - options.FindOne().SetProjection(bson.M{"wall": 1})).Decode(&oldest); err != nil { + m.ctx, + bson.M{"wall": bson.M{"$exists": true}}, + options.FindOne().SetSort("$natural")).Decode(&oldest); err != nil { return 0, err } + + log.Printf("oldest %v ", oldest) var newest MongoMetaData - if err := oplogC.FindOne(m.ctx, - bson.M{}, - options.FindOne().SetSort("-$natural"), - options.FindOne().SetProjection(bson.M{"wall": 1})).Decode(&newest); err != nil { + if err := oplogC.FindOne( + m.ctx, + bson.M{"wall": bson.M{"$exists": true}}, + options.FindOne().SetSort("-$natural")).Decode(&newest); err != nil { return 0, err } - oplogDuration := oldest.Wall.Sub(oldest.Wall) + log.Printf("newest %v ", newest) + oldestT := time.UnixMilli(oldest.Wall) + newestT := time.UnixMilli(newest.Wall) + oplogDuration := newestT.Sub(oldestT) log.Printf("oplog duration is currently: %v\n", oplogDuration) return oplogDuration, nil } From af1c825f5da5b93fd036f1a4e5ce4d1fec30f200 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 12 Dec 2023 11:57:19 +1300 Subject: [PATCH 025/413] sorting out duration --- .../20231128_jellyfish_migration.go | 40 ++++++++++++------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 49b67c985d..9002418a0a 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -216,32 +216,42 @@ func (m *Migration) execute() error { } func (m *Migration) getOplogDuration() (time.Duration, error) { - type MongoMetaData struct { - Wall int64 `json:"wall"` - } + // type MongoMetaData struct { + // Wall int64 `json:"wall"` + // } + log.Println("checking oplog duration ") if oplogC := m.getOplogCollection(); oplogC != nil { - var oldest MongoMetaData + oldest := map[string]interface{}{} - if err := oplogC.FindOne( + if result := oplogC.FindOne( m.ctx, bson.M{"wall": bson.M{"$exists": true}}, - options.FindOne().SetSort("$natural")).Decode(&oldest); err != nil { - return 0, err + options.FindOne().SetSort("$natural")); result != nil { + if result.Err() != nil { + return 0, result.Err() + } + result.Decode(&oldest) + log.Printf("oldest: %#v", oldest) } log.Printf("oldest %v ", oldest) - var newest MongoMetaData - if err := oplogC.FindOne( + //var newest MongoMetaData + newest := map[string]interface{}{} + + if result := oplogC.FindOne( m.ctx, bson.M{"wall": bson.M{"$exists": true}}, - options.FindOne().SetSort("-$natural")).Decode(&newest); err != nil { - return 0, err + options.FindOne().SetSort("-$natural")); result != nil { + if result.Err() != nil { + return 0, result.Err() + } + result.Decode(&newest) + log.Printf("newest: %#v", newest) } - log.Printf("newest %v ", newest) - oldestT := time.UnixMilli(oldest.Wall) - newestT := time.UnixMilli(newest.Wall) - oplogDuration := newestT.Sub(oldestT) + //oldestT := time.UnixMilli(oldest.Wall) + //newestT := time.UnixMilli(newest.Wall) + oplogDuration := time.Duration(0) //newestT.Sub(oldestT) log.Printf("oplog duration is currently: %v\n", oplogDuration) return oplogDuration, nil } From 2bd7ebf198e0bdb3c5f952afb6704df93df12b37 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 12 Dec 2023 14:12:35 +1300 Subject: [PATCH 026/413] update sort --- .../20231128_jellyfish_migration.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 9002418a0a..67925d1a1e 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -227,7 +227,9 @@ func (m *Migration) getOplogDuration() (time.Duration, error) { if result := oplogC.FindOne( m.ctx, bson.M{"wall": bson.M{"$exists": true}}, - options.FindOne().SetSort("$natural")); result != nil { + options.FindOne().SetSort(bson.M{"$natural": 1})); result != nil { + + log.Printf("oldest walltime mongo result %#v", result) if result.Err() != nil { return 0, result.Err() } @@ -242,7 +244,7 @@ func (m *Migration) getOplogDuration() (time.Duration, error) { if result := oplogC.FindOne( m.ctx, bson.M{"wall": bson.M{"$exists": true}}, - options.FindOne().SetSort("-$natural")); result != nil { + options.FindOne().SetSort(bson.M{"$natural": -1})); result != nil { if result.Err() != nil { return 0, result.Err() } From 1cf7e5899c5fb249d506258b62b614987ffde228 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 12 Dec 2023 14:32:21 +1300 Subject: [PATCH 027/413] just get the wall time --- .../20231128_jellyfish_migration.go | 46 +++++++------------ 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 67925d1a1e..9203f92e04 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -216,45 +216,33 @@ func (m *Migration) execute() error { } func (m *Migration) getOplogDuration() (time.Duration, error) { - // type MongoMetaData struct { - // Wall int64 `json:"wall"` - // } + type MongoMetaData struct { + Wall int64 `json:"wall"` + } log.Println("checking oplog duration ") if oplogC := m.getOplogCollection(); oplogC != nil { - oldest := map[string]interface{}{} - - if result := oplogC.FindOne( + oldest := MongoMetaData{} + if err := oplogC.FindOne( m.ctx, bson.M{"wall": bson.M{"$exists": true}}, - options.FindOne().SetSort(bson.M{"$natural": 1})); result != nil { - - log.Printf("oldest walltime mongo result %#v", result) - if result.Err() != nil { - return 0, result.Err() - } - result.Decode(&oldest) - log.Printf("oldest: %#v", oldest) + options.FindOne().SetSort(bson.M{"$natural": 1})).Decode(&oldest); err != nil { + log.Printf("oldest walltime mongo err %v", err) + return 0, err } - log.Printf("oldest %v ", oldest) - //var newest MongoMetaData - newest := map[string]interface{}{} - - if result := oplogC.FindOne( + newest := MongoMetaData{} + if err := oplogC.FindOne( m.ctx, bson.M{"wall": bson.M{"$exists": true}}, - options.FindOne().SetSort(bson.M{"$natural": -1})); result != nil { - if result.Err() != nil { - return 0, result.Err() - } - result.Decode(&newest) - log.Printf("newest: %#v", newest) + options.FindOne().SetSort(bson.M{"$natural": -1})).Decode(&newest); err != nil { + log.Printf("newest walltime mongo err %v", err) + return 0, err } - //oldestT := time.UnixMilli(oldest.Wall) - //newestT := time.UnixMilli(newest.Wall) - oplogDuration := time.Duration(0) //newestT.Sub(oldestT) - log.Printf("oplog duration is currently: %v\n", oplogDuration) + oldestT := time.UnixMilli(oldest.Wall) + newestT := time.UnixMilli(newest.Wall) + oplogDuration := newestT.Sub(oldestT) + log.Printf("oplog duration is currently: %v", oplogDuration) return oplogDuration, nil } log.Println("Not clustered, not retrieving oplog duration.") From fbeb0f8af51a6bfbd564e10737986441bf822c7c Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 12 Dec 2023 15:19:32 +1300 Subject: [PATCH 028/413] as time.Time --- .../20231128_jellyfish_migration.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 9203f92e04..d3aa7340ce 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -217,7 +217,7 @@ func (m *Migration) execute() error { func (m *Migration) getOplogDuration() (time.Duration, error) { type MongoMetaData struct { - Wall int64 `json:"wall"` + Wall time.Time `json:"wall"` } log.Println("checking oplog duration ") @@ -239,9 +239,9 @@ func (m *Migration) getOplogDuration() (time.Duration, error) { log.Printf("newest walltime mongo err %v", err) return 0, err } - oldestT := time.UnixMilli(oldest.Wall) - newestT := time.UnixMilli(newest.Wall) - oplogDuration := newestT.Sub(oldestT) + //oldestT := time.UnixMilli(oldest.Wall) + //newestT := time.UnixMilli(newest.Wall) + oplogDuration := newest.Wall.Sub(oldest.Wall) log.Printf("oplog duration is currently: %v", oplogDuration) return oplogDuration, nil } From 1d2a43330210e4ffee97354e742f31f6b06b825d Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 12 Dec 2023 17:00:12 +1300 Subject: [PATCH 029/413] test actual update but capped --- .../20231128_jellyfish_migration.go | 94 +++++++------------ 1 file changed, 34 insertions(+), 60 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index d3aa7340ce..c306b6212d 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -34,10 +34,9 @@ type Config struct { } type Migration struct { - ctx context.Context - cli *cli.App - config *Config - //*migrationMongo.Migration + ctx context.Context + cli *cli.App + config *Config client *mongo.Client writeBatchSize *int64 updates []mongo.WriteModel @@ -50,8 +49,6 @@ func main() { ctx := context.Background() ctx, cancel := context.WithCancel(ctx) defer cancel() - //application.RunAndExit(NewMigration(ctx)) - migration := NewMigration(ctx) migration.RunAndExit() log.Println("finished migration") @@ -59,9 +56,8 @@ func main() { func NewMigration(ctx context.Context) *Migration { return &Migration{ - ctx: ctx, - cli: cli.NewApp(), - //Migration: migrationMongo.NewMigration(), + ctx: ctx, + cli: cli.NewApp(), config: &Config{}, updates: []mongo.WriteModel{}, } @@ -90,7 +86,7 @@ func (m *Migration) RunAndExit() { log.Printf("execute failed: %s", err) return err } - log.Println("finished prepare") + log.Println("finished execute") return nil } @@ -103,11 +99,6 @@ func (m *Migration) RunAndExit() { } func (m *Migration) Initialize() error { - log.Println("init") - // if err := m.Migration.Initialize(provider); err != nil { - // return err - // } - m.CLI().Usage = "BACK-37: Migrate all existing data to add required Platform deduplication hash fields" m.CLI().Description = "BACK-37: To fully migrate devices from the `jellyfish` upload API to the `platform` upload API" m.CLI().Authors = []cli.Author{ @@ -117,12 +108,10 @@ func (m *Migration) Initialize() error { }, } m.CLI().Flags = append(m.CLI().Flags, - cli.BoolFlag{ Name: fmt.Sprintf("%s,%s", DryRunFlag, "n"), Usage: "dry run only; do not migrate", }, - cli.Int64Flag{ Name: "batch-size", Usage: "number of records to read each time", @@ -166,16 +155,6 @@ func (m *Migration) Initialize() error { Required: false, }, ) - - // m.CLI().Action = func(ctx *cli.Context) error { - // // if !m.ParseContext(ctx) { - // // return errors.New("could not parse context") - // // } - // if err := m.prepare(); err != nil { - // return nil - // } - // return m.execute() - // } return nil } @@ -203,6 +182,7 @@ func (m *Migration) prepare() error { func (m *Migration) execute() error { log.Println("about to run execute") totalMigrated := 0 + testingCapSize := 100 for m.fetchAndUpdateBatch() { updatedCount, err := m.writeBatchUpdates() if err != nil { @@ -211,36 +191,35 @@ func (m *Migration) execute() error { } totalMigrated = totalMigrated + updatedCount log.Printf("migrated %d for a total of %d migrated items", updatedCount, totalMigrated) + if totalMigrated >= testingCapSize { + log.Println("migrated docs up to cap so exiting") + break + } } return nil } func (m *Migration) getOplogDuration() (time.Duration, error) { + log.Println("checking oplog duration ...") type MongoMetaData struct { Wall time.Time `json:"wall"` } - - log.Println("checking oplog duration ") if oplogC := m.getOplogCollection(); oplogC != nil { - oldest := MongoMetaData{} + var oldest MongoMetaData if err := oplogC.FindOne( m.ctx, bson.M{"wall": bson.M{"$exists": true}}, options.FindOne().SetSort(bson.M{"$natural": 1})).Decode(&oldest); err != nil { - log.Printf("oldest walltime mongo err %v", err) return 0, err } - newest := MongoMetaData{} + var newest MongoMetaData if err := oplogC.FindOne( m.ctx, bson.M{"wall": bson.M{"$exists": true}}, options.FindOne().SetSort(bson.M{"$natural": -1})).Decode(&newest); err != nil { - log.Printf("newest walltime mongo err %v", err) return 0, err } - //oldestT := time.UnixMilli(oldest.Wall) - //newestT := time.UnixMilli(newest.Wall) oplogDuration := newest.Wall.Sub(oldest.Wall) log.Printf("oplog duration is currently: %v", oplogDuration) return oplogDuration, nil @@ -256,9 +235,8 @@ func calculateBatchSize(oplogSize int, oplogEntryBytes int, oplogMinWindow int, } func (m *Migration) setWriteBatchSize() error { - log.Println("set write batch size...") + log.Println("set writeBatchSize...") if oplogC := m.getOplogCollection(); oplogC != nil { - log.Println("Getting oplog stats...") type MongoMetaData struct { MaxSize int `json:"maxSize"` } @@ -285,19 +263,14 @@ func (m *Migration) checkFreeSpace() error { FsUsedSize int `json:"fsUsedSize"` } var metaData MongoMetaData - log.Println("Getting DB free space...") - if dataC := m.getDataCollection(); dataC != nil { - - err := dataC.Database().RunCommand(m.ctx, bson.M{"dbStats": 1}).Decode(&metaData) - if err != nil { + if err := dataC.Database().RunCommand(m.ctx, bson.M{"dbStats": 1}).Decode(&metaData); err != nil { return err } - log.Printf("DB free space: %v", metaData) + log.Printf("dbStats: %#v", metaData) bytesFree := metaData.FsTotalSize - metaData.FsUsedSize percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) log.Printf("DB disk currently has %d%% (%d bytes) free.", percentFree, bytesFree) - if m.config.minFreePercent > percentFree { return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) } @@ -307,7 +280,7 @@ func (m *Migration) checkFreeSpace() error { } func (m *Migration) getWaitTime() (float64, error) { - log.Println("Loading DB replication status...") + log.Println("getting wait time ...") type Member struct { Name string `json:"name"` @@ -321,8 +294,9 @@ func (m *Migration) getWaitTime() (float64, error) { } var metaData MongoMetaData - m.client.Database("admin").RunCommand(m.ctx, bson.M{"replSetGetStatus": 1}).Decode(&metaData) - log.Printf("DB replication status loaded. %#v", metaData) + if err := m.client.Database("admin").RunCommand(m.ctx, bson.M{"replSetGetStatus": 1}).Decode(&metaData); err != nil { + return 0, err + } for _, member := range metaData.Members { if member.State < 1 || member.State > 2 || member.Health != 1 || member.Uptime < 120 { @@ -335,10 +309,9 @@ func (m *Migration) getWaitTime() (float64, error) { if err != nil { return 0, err } - log.Printf("oplogDuration %v ", oplogDuration) if oplogDuration.Seconds() < float64(m.config.minOplogWindow) { minOplogWindowTime := time.Duration(m.config.minOplogWindow) * time.Second - log.Printf("DB OPLOG shorter than requested duration of %s, currently %s.", minOplogWindowTime, oplogDuration) + log.Printf("DB oplog shorter than requested duration of %s, currently %s.", minOplogWindowTime, oplogDuration) waitTime := float64(m.config.minOplogWindow) - oplogDuration.Seconds() waitTime *= 1.15 if waitTime < 600 { @@ -350,7 +323,7 @@ func (m *Migration) getWaitTime() (float64, error) { } func (m *Migration) blockUntilDBReady() error { - log.Println("blocking...") + log.Println("blocking until ready...") waitTime, err := m.getWaitTime() if err != nil { return err @@ -373,7 +346,6 @@ func (m *Migration) blockUntilDBReady() error { } func (m *Migration) fetchAndUpdateBatch() bool { - selector := bson.M{ // jellyfish uses a generated _id that is not an mongo objectId "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, @@ -382,7 +354,6 @@ func (m *Migration) fetchAndUpdateBatch() bool { "_userId": "5e8cac61-6bef-4728-b490-c1d82087ed9c", } m.updates = []mongo.WriteModel{} - if dataC := m.getDataCollection(); dataC != nil { dDataCursor, err := dataC.Find(m.ctx, selector, &options.FindOptions{Limit: &m.config.readBatchSize}, @@ -396,8 +367,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { defer dDataCursor.Close(m.ctx) for dDataCursor.Next(m.ctx) { - err = dDataCursor.Decode(&dDataResult) - if err != nil { + if err = dDataCursor.Decode(&dDataResult); err != nil { log.Printf("failed decoding data: %s", err) return false } @@ -424,12 +394,12 @@ func (m *Migration) fetchAndUpdateBatch() bool { } return len(m.updates) > 0 } - log.Println("get deviceData collection ") return false } func (m *Migration) writeBatchUpdates() (int, error) { var getBatches = func(chunkSize int) [][]mongo.WriteModel { + log.Printf("updates to apply count: %d", len(m.updates)) batches := [][]mongo.WriteModel{} for i := 0; i < len(m.updates); i += chunkSize { end := i + chunkSize @@ -455,11 +425,15 @@ func (m *Migration) writeBatchUpdates() (int, error) { updateCount += len(batch) log.Printf("updates applied so far %d", updateCount) - // results, err := m.deviceDataC.BulkWrite(m.ctx, batch) - // if err != nil { - // return updateCount, err - // } - // updateCount = updateCount + int(results.ModifiedCount) + if deviceC := m.getDataCollection(); deviceC != nil { + results, err := deviceC.BulkWrite(m.ctx, batch) + if err != nil { + log.Printf("error writing batch updates %v", err) + return updateCount, err + } + log.Printf("update resuts %#v", results) + updateCount = updateCount + int(results.ModifiedCount) + } } log.Printf("applied %d updates", updateCount) return updateCount, nil From 494c8d877fd77e55fb19ea35b02f716d4e985fda Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 12 Dec 2023 18:01:07 +1300 Subject: [PATCH 030/413] load URI from file --- .../20231128_jellyfish_migration.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index c306b6212d..092ba96308 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -7,6 +7,7 @@ import ( "log" "math" "os" + "strings" "time" "github.com/urfave/cli" @@ -69,9 +70,9 @@ func (m *Migration) RunAndExit() { } m.CLI().Action = func(ctx *cli.Context) error { - log.Println("running") var err error - m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(m.config.uri)) + mongoURI := strings.ReplaceAll(m.config.uri, " ", "") + m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(mongoURI)) if err != nil { return fmt.Errorf("unable to connect to MongoDB: %w", err) } @@ -151,10 +152,12 @@ func (m *Migration) Initialize() error { Name: "uri", Usage: "mongo connection URI", Destination: &m.config.uri, - Value: "mongodb://localhost:27017", + Value: "", Required: false, + FilePath: "./uri", }, ) + return nil } From 9ac09a63a053ee0607d4492f082da5bc2a3e26c9 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 12 Dec 2023 21:16:10 +1300 Subject: [PATCH 031/413] uri from file --- .../20231128_jellyfish_migration.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 092ba96308..e7301664e2 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -71,8 +71,7 @@ func (m *Migration) RunAndExit() { m.CLI().Action = func(ctx *cli.Context) error { var err error - mongoURI := strings.ReplaceAll(m.config.uri, " ", "") - m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(mongoURI)) + m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(strings.TrimSpace(m.config.uri))) if err != nil { return fmt.Errorf("unable to connect to MongoDB: %w", err) } @@ -152,7 +151,6 @@ func (m *Migration) Initialize() error { Name: "uri", Usage: "mongo connection URI", Destination: &m.config.uri, - Value: "", Required: false, FilePath: "./uri", }, From edb2c146e915c74ae8d0b778dbd8030b33b7eace Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 13 Dec 2023 11:47:47 +1300 Subject: [PATCH 032/413] debug bulk updates --- .../20231128_jellyfish_migration.go | 10 +- .../connect/connect.go | 217 ------------------ 2 files changed, 7 insertions(+), 220 deletions(-) delete mode 100644 migrations/20231128_jellyfish_migration/connect/connect.go diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index e7301664e2..5185947cf0 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -183,7 +183,7 @@ func (m *Migration) prepare() error { func (m *Migration) execute() error { log.Println("about to run execute") totalMigrated := 0 - testingCapSize := 100 + testingCapSize := 10 for m.fetchAndUpdateBatch() { updatedCount, err := m.writeBatchUpdates() if err != nil { @@ -364,10 +364,9 @@ func (m *Migration) fetchAndUpdateBatch() bool { return false } - var dDataResult bson.M - defer dDataCursor.Close(m.ctx) for dDataCursor.Next(m.ctx) { + var dDataResult bson.M if err = dDataCursor.Decode(&dDataResult); err != nil { log.Printf("failed decoding data: %s", err) return false @@ -385,6 +384,8 @@ func (m *Migration) fetchAndUpdateBatch() bool { return false } + log.Printf("updates [%s] to apply [%#v]", datumID, updates) + m.updates = append(m.updates, mongo.NewUpdateOneModel().SetFilter( bson.M{ "_id": datumID, @@ -393,6 +394,9 @@ func (m *Migration) fetchAndUpdateBatch() bool { "$set": updates, })) } + + log.Printf("all updates [%#v]", m.updates) + return len(m.updates) > 0 } return false diff --git a/migrations/20231128_jellyfish_migration/connect/connect.go b/migrations/20231128_jellyfish_migration/connect/connect.go deleted file mode 100644 index 754d81b71c..0000000000 --- a/migrations/20231128_jellyfish_migration/connect/connect.go +++ /dev/null @@ -1,217 +0,0 @@ -package main - -import ( - "context" - "fmt" - "log" - "math" - "os" - - "github.com/urfave/cli" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" -) - -type Config struct { - uri string - minOplogWindow int - // these values are used to determine writes batches, first dividing the oplog's size with the desired duration and - // expected entry size, then adding a divisor to account for NOP overshoot in the oplog - expectedOplogEntrySize int - // how much of the oplog is NOP, this adjusts the batch to account for an oplog that is very change sensitive - // must be > 0 - // prod 0.6 - // idle 100 - nopPercent int - // minimum free disk space percent - minFreePercent int - readBatchSize int64 -} - -type Migration struct { - cli *cli.App - ctx context.Context - config *Config - client *mongo.Client - oplogC *mongo.Collection - deviceDataC *mongo.Collection - writeBatchSize *int64 - updates []mongo.WriteModel -} - -const oplogName = "oplog.rs" - -func main() { - ctx := context.Background() - ctx, cancel := context.WithCancel(ctx) - defer cancel() - migration := NewMigration(ctx) - migration.RunAndExit() -} - -func NewMigration(ctx context.Context) *Migration { - return &Migration{ - cli: cli.NewApp(), - ctx: ctx, - config: &Config{}, - updates: []mongo.WriteModel{}, - } -} - -func (m *Migration) RunAndExit() { - if err := m.Initialize(); err != nil { - os.Exit(1) - } - - m.CLI().Action = func(ctx *cli.Context) error { - log.Println("before prepare") - if err := m.prepare(); err != nil { - log.Printf("error %s", err) - return err - } - return nil - } - - if err := m.CLI().Run(os.Args); err != nil { - os.Exit(1) - } - - os.Exit(0) -} - -func (m *Migration) CLI() *cli.App { - return m.cli -} - -func (m *Migration) Initialize() error { - - log.Println("Initialize...") - - m.CLI().Usage = "BACK-37: Migrate all existing data to add required Platform deduplication hash fields" - m.CLI().Description = "BACK-37: To fully migrate devices from the `jellyfish` upload API to the `platform` upload API" - m.CLI().Authors = []cli.Author{ - { - Name: "J H BATE", - Email: "jamie@tidepool.org", - }, - } - m.CLI().Flags = append(m.CLI().Flags, - cli.Int64Flag{ - Name: "batch-size", - Usage: "number of records to read each time", - Destination: &m.config.readBatchSize, - Value: 3000, - Required: false, - }, - cli.IntFlag{ - Name: "min-free-percent", - Usage: "minimum free disk space percent", - Destination: &m.config.minFreePercent, - Value: 10, - Required: false, - }, - cli.IntFlag{ - Name: "nop-percent", - Usage: "how much of the oplog is NOP", - Destination: &m.config.nopPercent, - Value: 100, - Required: false, - }, - cli.IntFlag{ - Name: "oplog-entry-size", - Usage: "minimum free disk space percent", - Destination: &m.config.expectedOplogEntrySize, - Value: 420, - Required: false, - }, - cli.IntFlag{ - Name: "oplog-window", - Usage: "minimum oplog window in seconds", - Destination: &m.config.minOplogWindow, - Value: 28800, // 8hrs - Required: false, - }, - cli.StringFlag{ - Name: "uri", - Usage: "mongo connection URI", - Destination: &m.config.uri, - Value: "mongodb://localhost:27017", - Required: false, - }, - ) - return nil -} - -func (m *Migration) prepare() error { - log.Println("Prepare ...") - var err error - m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(m.config.uri)) - if err != nil { - return fmt.Errorf("unable to connect to MongoDB: %w", err) - } - defer m.client.Disconnect(m.ctx) - - m.oplogC = m.client.Database("local").Collection(oplogName) - m.deviceDataC = m.client.Database("data").Collection("deviceData") - - if err := m.checkFreeSpace(); err != nil { - return err - } - - err = m.setWriteBatchSize() - if err != nil { - return err - } - return nil -} - -func (m *Migration) setWriteBatchSize() error { - if m.oplogC != nil { - log.Println("Getting Write Batch Size...") - type MongoMetaData struct { - MaxSize int `json:"maxSize"` - } - var metaData MongoMetaData - if err := m.oplogC.Database().RunCommand(m.ctx, bson.M{"collStats": oplogName}).Decode(&metaData); err != nil { - return err - } - log.Printf("oplogSize... %v", metaData.MaxSize) - writeBatchSize := int64(math.Floor( - float64(metaData.MaxSize) / - float64(m.config.expectedOplogEntrySize) / - float64(m.config.minOplogWindow) / - (float64(m.config.nopPercent) / float64(7)))) - log.Printf("writeBatchSize... %v", writeBatchSize) - m.writeBatchSize = &writeBatchSize - return nil - } - var writeBatchSize = int64(30000) - log.Printf("MongoDB is not clustered, removing write batch limit, setting to %d documents.", writeBatchSize) - m.writeBatchSize = &writeBatchSize - return nil -} - -func (m *Migration) checkFreeSpace() error { - log.Println("check free space...") - type MongoMetaData struct { - FsTotalSize int `json:"fsTotalSize"` - FsUsedSize int `json:"fsUsedSize"` - } - var metaData MongoMetaData - log.Println("Getting DB free space...") - err := m.deviceDataC.Database().RunCommand(m.ctx, bson.M{"dbStats": 1}).Decode(&metaData) - if err != nil { - - return err - } - log.Printf("DB free space: %v", metaData) - bytesFree := metaData.FsTotalSize - metaData.FsUsedSize - percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) - log.Printf("DB disk currently has %d%% (%d) free.", percentFree*100, bytesFree) - - if m.config.minFreePercent > percentFree { - return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) - } - return nil -} From 0398ef0a363433d0ef20aac983bf9a145976b3b7 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 13 Dec 2023 11:48:32 +1300 Subject: [PATCH 033/413] seconds to millis --- data/types/device/override/settings/pump/pump.go | 2 +- data/types/device/override/settings/pump/pump_test.go | 2 +- data/types/settings/pump/override_preset.go | 2 +- data/types/settings/pump/override_preset_test.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/types/device/override/settings/pump/pump.go b/data/types/device/override/settings/pump/pump.go index 735cde3059..21ad0bd430 100644 --- a/data/types/device/override/settings/pump/pump.go +++ b/data/types/device/override/settings/pump/pump.go @@ -15,7 +15,7 @@ const ( BasalRateScaleFactorMinimum = 0.1 CarbohydrateRatioScaleFactorMaximum = 10.0 CarbohydrateRatioScaleFactorMinimum = 0.1 - DurationMaximum = 604800 // 7 days in seconds + DurationMaximum = 604800000 // 7 days in milliseconds DurationMinimum = 0 InsulinSensitivityScaleFactorMaximum = 10.0 InsulinSensitivityScaleFactorMinimum = 0.1 diff --git a/data/types/device/override/settings/pump/pump_test.go b/data/types/device/override/settings/pump/pump_test.go index 74001b91a9..53dd8a20a6 100644 --- a/data/types/device/override/settings/pump/pump_test.go +++ b/data/types/device/override/settings/pump/pump_test.go @@ -48,7 +48,7 @@ var _ = Describe("Pump", func() { }) It("DurationMaximum is expected", func() { - Expect(dataTypesDeviceOverrideSettingsPump.DurationMaximum).To(Equal(604800)) + Expect(dataTypesDeviceOverrideSettingsPump.DurationMaximum).To(Equal(604800000)) }) It("DurationMinimum is expected", func() { diff --git a/data/types/settings/pump/override_preset.go b/data/types/settings/pump/override_preset.go index 8e8148fc8b..df14a81552 100644 --- a/data/types/settings/pump/override_preset.go +++ b/data/types/settings/pump/override_preset.go @@ -15,7 +15,7 @@ const ( BasalRateScaleFactorMinimum = 0.1 CarbohydrateRatioScaleFactorMaximum = 10.0 CarbohydrateRatioScaleFactorMinimum = 0.1 - DurationMaximum = 604800 // 7 days in seconds + DurationMaximum = 604800000 // 7 days in milliseconds DurationMinimum = 0 InsulinSensitivityScaleFactorMaximum = 10.0 InsulinSensitivityScaleFactorMinimum = 0.1 diff --git a/data/types/settings/pump/override_preset_test.go b/data/types/settings/pump/override_preset_test.go index 2007eabefb..4fee4045bb 100644 --- a/data/types/settings/pump/override_preset_test.go +++ b/data/types/settings/pump/override_preset_test.go @@ -40,7 +40,7 @@ var _ = Describe("OverridePreset", func() { }) It("DurationMaximum is expected", func() { - Expect(dataTypesSettingsPump.DurationMaximum).To(Equal(604800)) + Expect(dataTypesSettingsPump.DurationMaximum).To(Equal(604800000)) }) It("DurationMinimum is expected", func() { From 36b643602d8d2d776335c8534367142c63086083 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 13 Dec 2023 13:12:10 +1300 Subject: [PATCH 034/413] use dry run flag --- .../20231128_jellyfish_migration.go | 50 ++++++++----------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 5185947cf0..b841ed3c58 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -41,6 +41,7 @@ type Migration struct { client *mongo.Client writeBatchSize *int64 updates []mongo.WriteModel + dryRun bool } const oplogName = "oplog.rs" @@ -61,6 +62,7 @@ func NewMigration(ctx context.Context) *Migration { cli: cli.NewApp(), config: &Config{}, updates: []mongo.WriteModel{}, + dryRun: true, } } @@ -76,7 +78,6 @@ func (m *Migration) RunAndExit() { return fmt.Errorf("unable to connect to MongoDB: %w", err) } defer m.client.Disconnect(m.ctx) - log.Printf("config %#v", m.config) if err := m.prepare(); err != nil { log.Printf("prepare failed: %s", err) @@ -86,7 +87,6 @@ func (m *Migration) RunAndExit() { log.Printf("execute failed: %s", err) return err } - log.Println("finished execute") return nil } @@ -109,8 +109,9 @@ func (m *Migration) Initialize() error { } m.CLI().Flags = append(m.CLI().Flags, cli.BoolFlag{ - Name: fmt.Sprintf("%s,%s", DryRunFlag, "n"), - Usage: "dry run only; do not migrate", + Name: fmt.Sprintf("%s,%s", DryRunFlag, "n"), + Usage: "dry run only; do not migrate", + Destination: &m.dryRun, }, cli.Int64Flag{ Name: "batch-size", @@ -155,7 +156,6 @@ func (m *Migration) Initialize() error { FilePath: "./uri", }, ) - return nil } @@ -181,7 +181,6 @@ func (m *Migration) prepare() error { } func (m *Migration) execute() error { - log.Println("about to run execute") totalMigrated := 0 testingCapSize := 10 for m.fetchAndUpdateBatch() { @@ -201,7 +200,6 @@ func (m *Migration) execute() error { } func (m *Migration) getOplogDuration() (time.Duration, error) { - log.Println("checking oplog duration ...") type MongoMetaData struct { Wall time.Time `json:"wall"` } @@ -222,7 +220,7 @@ func (m *Migration) getOplogDuration() (time.Duration, error) { return 0, err } oplogDuration := newest.Wall.Sub(oldest.Wall) - log.Printf("oplog duration is currently: %v", oplogDuration) + log.Printf("oplog duration: %v", oplogDuration) return oplogDuration, nil } log.Println("Not clustered, not retrieving oplog duration.") @@ -236,7 +234,6 @@ func calculateBatchSize(oplogSize int, oplogEntryBytes int, oplogMinWindow int, } func (m *Migration) setWriteBatchSize() error { - log.Println("set writeBatchSize...") if oplogC := m.getOplogCollection(); oplogC != nil { type MongoMetaData struct { MaxSize int `json:"maxSize"` @@ -245,10 +242,9 @@ func (m *Migration) setWriteBatchSize() error { if err := oplogC.Database().RunCommand(m.ctx, bson.M{"collStats": oplogName}).Decode(&metaData); err != nil { return err } - log.Printf("oplog maxSize: %d", metaData.MaxSize) writeBatchSize := calculateBatchSize(metaData.MaxSize, m.config.expectedOplogEntrySize, m.config.minOplogWindow, m.config.nopPercent) m.writeBatchSize = &writeBatchSize - log.Printf("writeBatchSize: %d", writeBatchSize) + log.Printf("calculated writeBatchSize: %d", writeBatchSize) return nil } var writeBatchSize = int64(30000) @@ -258,7 +254,6 @@ func (m *Migration) setWriteBatchSize() error { } func (m *Migration) checkFreeSpace() error { - log.Println("check free space...") type MongoMetaData struct { FsTotalSize int `json:"fsTotalSize"` FsUsedSize int `json:"fsUsedSize"` @@ -268,7 +263,6 @@ func (m *Migration) checkFreeSpace() error { if err := dataC.Database().RunCommand(m.ctx, bson.M{"dbStats": 1}).Decode(&metaData); err != nil { return err } - log.Printf("dbStats: %#v", metaData) bytesFree := metaData.FsTotalSize - metaData.FsUsedSize percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) log.Printf("DB disk currently has %d%% (%d bytes) free.", percentFree, bytesFree) @@ -281,8 +275,6 @@ func (m *Migration) checkFreeSpace() error { } func (m *Migration) getWaitTime() (float64, error) { - log.Println("getting wait time ...") - type Member struct { Name string `json:"name"` Health int `json:"health"` @@ -355,9 +347,11 @@ func (m *Migration) fetchAndUpdateBatch() bool { "_userId": "5e8cac61-6bef-4728-b490-c1d82087ed9c", } m.updates = []mongo.WriteModel{} + sLimit := int64(5) //Testing only get small group at a time if dataC := m.getDataCollection(); dataC != nil { dDataCursor, err := dataC.Find(m.ctx, selector, - &options.FindOptions{Limit: &m.config.readBatchSize}, + //&options.FindOptions{Limit: &m.config.readBatchSize}, + &options.FindOptions{Limit: &sLimit}, ) if err != nil { log.Printf("failed to select data: %s", err) @@ -384,7 +378,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { return false } - log.Printf("updates [%s] to apply [%#v]", datumID, updates) + log.Printf("updates [%s] to apply [%#v] using [%#v]", datumID, updates, dDataResult) m.updates = append(m.updates, mongo.NewUpdateOneModel().SetFilter( bson.M{ @@ -394,9 +388,6 @@ func (m *Migration) fetchAndUpdateBatch() bool { "$set": updates, })) } - - log.Printf("all updates [%#v]", m.updates) - return len(m.updates) > 0 } return false @@ -429,16 +420,19 @@ func (m *Migration) writeBatchUpdates() (int, error) { log.Printf("updates to write %d", len(batch)) updateCount += len(batch) - log.Printf("updates applied so far %d", updateCount) - if deviceC := m.getDataCollection(); deviceC != nil { - results, err := deviceC.BulkWrite(m.ctx, batch) - if err != nil { - log.Printf("error writing batch updates %v", err) - return updateCount, err + m.dryRun = true + + if !m.dryRun { + if deviceC := m.getDataCollection(); deviceC != nil { + results, err := deviceC.BulkWrite(m.ctx, batch) + if err != nil { + log.Printf("error writing batch updates %v", err) + return updateCount, err + } + updateCount = updateCount + int(results.ModifiedCount) } - log.Printf("update resuts %#v", results) - updateCount = updateCount + int(results.ModifiedCount) } + } log.Printf("applied %d updates", updateCount) return updateCount, nil From 793562a73908cd70e5ff115afe70e7307ed930eb Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 13 Dec 2023 15:16:26 +1300 Subject: [PATCH 035/413] sort query and set last updated to use --- .../20231128_jellyfish_migration.go | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index b841ed3c58..8dd66d55b6 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -42,6 +42,7 @@ type Migration struct { writeBatchSize *int64 updates []mongo.WriteModel dryRun bool + lastUpdatedId string } const oplogName = "oplog.rs" @@ -117,7 +118,7 @@ func (m *Migration) Initialize() error { Name: "batch-size", Usage: "number of records to read each time", Destination: &m.config.readBatchSize, - Value: 30, + Value: 10, Required: false, }, cli.IntFlag{ @@ -182,7 +183,7 @@ func (m *Migration) prepare() error { func (m *Migration) execute() error { totalMigrated := 0 - testingCapSize := 10 + testingCapSize := 20 for m.fetchAndUpdateBatch() { updatedCount, err := m.writeBatchUpdates() if err != nil { @@ -220,7 +221,7 @@ func (m *Migration) getOplogDuration() (time.Duration, error) { return 0, err } oplogDuration := newest.Wall.Sub(oldest.Wall) - log.Printf("oplog duration: %v", oplogDuration) + log.Printf("current oplog duration: %v", oplogDuration) return oplogDuration, nil } log.Println("Not clustered, not retrieving oplog duration.") @@ -316,7 +317,6 @@ func (m *Migration) getWaitTime() (float64, error) { } func (m *Migration) blockUntilDBReady() error { - log.Println("blocking until ready...") waitTime, err := m.getWaitTime() if err != nil { return err @@ -346,12 +346,25 @@ func (m *Migration) fetchAndUpdateBatch() bool { // testing based on _userId for jamie+qa3_1@tidepool.org "_userId": "5e8cac61-6bef-4728-b490-c1d82087ed9c", } + + if m.lastUpdatedId != "" { + selector["_id"] = bson.M{"$and": []interface{}{ + bson.M{"$gt": m.lastUpdatedId}, + bson.M{"$type": "objectId"}, + }} + log.Printf("selector with _id $gt %#v", selector) + } + m.updates = []mongo.WriteModel{} sLimit := int64(5) //Testing only get small group at a time + if dataC := m.getDataCollection(); dataC != nil { dDataCursor, err := dataC.Find(m.ctx, selector, //&options.FindOptions{Limit: &m.config.readBatchSize}, - &options.FindOptions{Limit: &sLimit}, + &options.FindOptions{ + Limit: &sLimit, + Sort: bson.M{"_id": 1}, + }, ) if err != nil { log.Printf("failed to select data: %s", err) @@ -387,6 +400,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { }).SetUpdate(bson.M{ "$set": updates, })) + m.lastUpdatedId = datumID } return len(m.updates) > 0 } From 05564f1f685df7f4c398d7b66ee422869334177e Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 13 Dec 2023 15:42:49 +1300 Subject: [PATCH 036/413] update selector --- .../20231128_jellyfish_migration.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 8dd66d55b6..8c4a16195f 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -341,18 +341,18 @@ func (m *Migration) blockUntilDBReady() error { func (m *Migration) fetchAndUpdateBatch() bool { selector := bson.M{ // jellyfish uses a generated _id that is not an mongo objectId - "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, "_deduplicator": bson.M{"$exists": false}, // testing based on _userId for jamie+qa3_1@tidepool.org "_userId": "5e8cac61-6bef-4728-b490-c1d82087ed9c", } if m.lastUpdatedId != "" { - selector["_id"] = bson.M{"$and": []interface{}{ - bson.M{"$gt": m.lastUpdatedId}, - bson.M{"$type": "objectId"}, - }} - log.Printf("selector with _id $gt %#v", selector) + selector["$and"] = []interface{}{ + bson.M{"_id": bson.M{"$gt": m.lastUpdatedId}}, + bson.M{"_id": bson.M{"$not": bson.M{"$type": "objectId"}}}, + } + } else { + selector["_id"] = bson.M{"$not": bson.M{"$type": "objectId"}} } m.updates = []mongo.WriteModel{} From 01d34d9c864aaf9548b356685ca7bb6143aa8f54 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 13 Dec 2023 16:52:04 +1300 Subject: [PATCH 037/413] get IdentityFields from actual datatype --- .../20231128_jellyfish_migration/test.json | 135 ++++++++++++++++++ .../utils/utils.go | 106 +++++++++++++- 2 files changed, 239 insertions(+), 2 deletions(-) create mode 100644 migrations/20231128_jellyfish_migration/test.json diff --git a/migrations/20231128_jellyfish_migration/test.json b/migrations/20231128_jellyfish_migration/test.json new file mode 100644 index 0000000000..61c38dc9c1 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/test.json @@ -0,0 +1,135 @@ +[ + "006j3omlmfijf7ifks6kkja2kdjjhlsk", + { + "_deduplicator": { "hash": "8cZ6O9FevUGu0UAqWzcpayBEov+R320ERRD/DKCJEQo=" } + }, + { + "_active": true, + "_groupId": "d7762454ad", + "_id": "006j3omlmfijf7ifks6kkja2kdjjhlsk", + "_userId": "5e8cac61-6bef-4728-b490-c1d82087ed9c", + "_version": 0, + "clockDriftOffset": 0, + "conversionOffset": 0, + "createdTime": 1701313771417, + "deliveryType": "automated", + "deviceId": "tandemCIQ10027171066407", + "deviceTime": "2023-10-18T05:21:49", + "duration": 601000, + "guid": "0b9e6f52-8406-4e02-9c9d-fe1704535a73", + "id": "utcutdn65391j2s0nj11ecl9qv8lo7bv", + "modifiedTime": 1701313771417, + "rate": 1.2, + "suppressed": { "deliveryType": "scheduled", "rate": 1.2, "type": "basal" }, + "time": 1697559709000, + "timezoneOffset": 780, + "type": "basal", + "uploadId": "upid_95cb50bf426d" + }, + + "006q5m29ba3ehqm9v8ra9l36rtcdfa4d", + { + "_deduplicator": { "hash": "8cZ6O9FevUGu0UAqWzcpayBEov+R320ERRD/DKCJEQo=" } + }, + { + "_active": true, + "_groupId": "d7762454ad", + "_id": "006q5m29ba3ehqm9v8ra9l36rtcdfa4d", + "_userId": "5e8cac61-6bef-4728-b490-c1d82087ed9c", + "_version": 0, + "clockDriftOffset": -158000, + "conversionOffset": 0, + "createdTime": 1701313654014, + "deliveryType": "automated", + "deviceId": "tandemCIQ10027171066407", + "deviceTime": "2023-09-13T15:27:37", + "duration": 301000, + "guid": "a4ad9653-34b8-48ac-b83f-018b7b6d6b55", + "id": "qijmfaopb2jm5sfkhgm2eogl1vak702u", + "modifiedTime": 1701313654014, + "rate": 0.123, + "suppressed": { "deliveryType": "scheduled", "rate": 0.9, "type": "basal" }, + "time": 1694575657000, + "timezoneOffset": 720, + "type": "basal", + "uploadId": "upid_95cb50bf426d" + }, + "006qgkujndr8854pql2bct8b0s59crrg", + { + "_deduplicator": { "hash": "PJwR47UL7JvZUrqgapgiG8KJhOEdwWWWuaC/SIE/s6M=" } + }, + { + "_active": true, + "_groupId": "d7762454ad", + "_id": "006qgkujndr8854pql2bct8b0s59crrg", + "_userId": "5e8cac61-6bef-4728-b490-c1d82087ed9c", + "_version": 0, + "clockDriftOffset": 0, + "conversionOffset": 0, + "createdTime": 1701313853944, + "deviceId": "tandemCIQ10027171066407", + "deviceTime": "2023-11-13T01:12:30", + "guid": "45b69cb3-6268-4174-90b3-a790665e0acf", + "id": "9i9hsb27i11uirg60safrcfdujugsv0u", + "modifiedTime": 1701313853944, + "rate": -3, + "rssi": -88, + "timestamp": 500692350, + "time": 1699791150000, + "timezoneOffset": 780, + "type": "cbg", + "units": "mmol/L", + "uploadId": "upid_95cb50bf426d", + "value": 5.217703111582802 + }, + "009d3ntunue9ekdpa5sajcm8qnd9mrm2", + { + "_deduplicator": { "hash": "w1DGKyl5uQcvv3mMXG2zN4ifvFU/7t6lAmcgHvjnC6o=" } + }, + { + "_active": true, + "_groupId": "d7762454ad", + "_id": "009d3ntunue9ekdpa5sajcm8qnd9mrm2", + "_userId": "5e8cac61-6bef-4728-b490-c1d82087ed9c", + "_version": 0, + "clockDriftOffset": -158000, + "conversionOffset": 0, + "createdTime": 1701313671438, + "deviceId": "tandemCIQ10027171066407", + "deviceTime": "2023-09-18T12:03:43", + "guid": "a7169991-51c5-46d0-ab93-b663a097759f", + "id": "alrb1615n8eru2r6b0js9077j44tikhq", + "modifiedTime": 1701313671438, + "time": 1694995423000, + "timezoneOffset": 720, + "type": "cbg", + "units": "mmol/L", + "uploadId": "upid_95cb50bf426d", + "value": 9.047719225404219 + }, + "00akqvf80nioro5l9noq1tgvh6srsope", + { + "_deduplicator": { "hash": "3LziAIxBKna0rS9/LSjHRMdy0eJGsFTIsaeVzaPNCEA=" } + }, + { + "_active": true, + "_groupId": "d7762454ad", + "_id": "00akqvf80nioro5l9noq1tgvh6srsope", + "_userId": "5e8cac61-6bef-4728-b490-c1d82087ed9c", + "_version": 0, + "clockDriftOffset": 0, + "conversionOffset": 0, + "createdTime": 1701313762010, + "deviceId": "tandemCIQ10027171066407", + "deviceTime": "2023-10-15T19:00:48", + "guid": "8f52ccf4-ce88-485c-9aa4-fe5cc82f5abb", + "id": "q2fqkdv7h9rolg7u14r16p1fc2cb1vo0", + "modifiedTime": 1701313762010, + "time": 1697349648000, + "timezoneOffset": 780, + "type": "cbg", + "units": "mmol/L", + "uploadId": "upid_95cb50bf426d", + "value": 5.7172704307769 + } +] diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index ec4e7bbb5c..4fed726134 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -41,7 +41,7 @@ func getValidatedTime(bsonData bson.M, fieldName string) (string, error) { if valRaw, ok := bsonData[fieldName]; !ok { return "", errors.Newf("%s is missing", fieldName) } else if ms, ok := valRaw.(int64); !ok { - if t := time.Unix(0, ms*int64(time.Millisecond)); !t.IsZero() { + if t := time.UnixMilli(ms); !t.IsZero() { return t.Format(types.TimeFormat), nil } } @@ -49,7 +49,7 @@ func getValidatedTime(bsonData bson.M, fieldName string) (string, error) { return "", errors.Newf("%s is missing", fieldName) } -func datumHash(bsonData bson.M) (string, error) { +func datumHash_1(bsonData bson.M) (string, error) { identityFields := []string{} if datumUserID, err := GetValidatedString(bsonData, "_userId"); err != nil { @@ -114,6 +114,108 @@ func datumHash(bsonData bson.M) (string, error) { return deduplicator.GenerateIdentityHash(identityFields) } +func datumHash(bsonData bson.M) (string, error) { + + datumType, err := GetValidatedString(bsonData, "type") + if err != nil { + log.Printf("invalid data type: %#v", bsonData) + return "", err + } + identityFields := []string{} + + switch datumType { + case basal.Type: + var basalDatum *basal.Basal + bsonBytes, err := bson.Marshal(bsonData) + if err != nil { + return "", err + } + bson.Unmarshal(bsonBytes, &basalDatum) + identityFields, err = basalDatum.IdentityFields() + if err != nil { + return "", err + } + case bolus.Type: + var bolusDatum *bolus.Bolus + bsonBytes, err := bson.Marshal(bsonData) + if err != nil { + return "", err + } + bson.Unmarshal(bsonBytes, &bolusDatum) + identityFields, err = bolusDatum.IdentityFields() + if err != nil { + return "", err + } + case device.Type: + var deviceDatum *device.Device + bsonBytes, err := bson.Marshal(bsonData) + if err != nil { + return "", err + } + bson.Unmarshal(bsonBytes, &deviceDatum) + identityFields, err = deviceDatum.IdentityFields() + if err != nil { + return "", err + } + case selfmonitored.Type: + var smbgDatum *selfmonitored.SelfMonitored + bsonBytes, err := bson.Marshal(bsonData) + if err != nil { + return "", err + } + bson.Unmarshal(bsonBytes, &smbgDatum) + if *smbgDatum.Units != glucose.MgdL && *smbgDatum.Units != glucose.Mgdl { + // NOTE: we need to ensure the same precision for the + // converted value as it is used to calculate the hash + val := GetBGValuePlatformPrecision(*smbgDatum.Value) + smbgDatum.Value = &val + } + identityFields, err = smbgDatum.IdentityFields() + if err != nil { + return "", err + } + case ketone.Type: + var ketoneDatum *ketone.Ketone + bsonBytes, err := bson.Marshal(bsonData) + if err != nil { + return "", err + } + bson.Unmarshal(bsonBytes, &ketoneDatum) + if *ketoneDatum.Units != glucose.MgdL && *ketoneDatum.Units != glucose.Mgdl { + // NOTE: we need to ensure the same precision for the + // converted value as it is used to calculate the hash + val := GetBGValuePlatformPrecision(*ketoneDatum.Value) + ketoneDatum.Value = &val + } + + identityFields, err = ketoneDatum.IdentityFields() + if err != nil { + return "", err + } + case continuous.Type: + var cbgDatum *continuous.Continuous + bsonBytes, err := bson.Marshal(bsonData) + if err != nil { + return "", err + } + bson.Unmarshal(bsonBytes, &cbgDatum) + + if *cbgDatum.Units != glucose.MgdL && *cbgDatum.Units != glucose.Mgdl { + // NOTE: we need to ensure the same precision for the + // converted value as it is used to calculate the hash + val := GetBGValuePlatformPrecision(*cbgDatum.Value) + cbgDatum.Value = &val + } + + identityFields, err = cbgDatum.IdentityFields() + if err != nil { + return "", err + } + + } + return deduplicator.GenerateIdentityHash(identityFields) +} + func updateIfExistsPumpSettingsSleepSchedules(bsonData bson.M) (*pump.SleepScheduleMap, error) { dataType, err := GetValidatedString(bsonData, "type") if err != nil { From 44d53d58645bf531b27abee889863c24bc4705eb Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 13 Dec 2023 17:16:42 +1300 Subject: [PATCH 038/413] debug for hash creation --- .../20231128_jellyfish_migration.go | 2 +- .../utils/utils.go | 59 ++++++++++--------- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 8c4a16195f..528cd35e0c 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -391,7 +391,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { return false } - log.Printf("updates [%s] to apply [%#v] using [%#v]", datumID, updates, dDataResult) + log.Printf("[id=%s] [%v]", datumID, updates) m.updates = append(m.updates, mongo.NewUpdateOneModel().SetFilter( bson.M{ diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 4fed726134..015419f45e 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -116,54 +116,59 @@ func datumHash_1(bsonData bson.M) (string, error) { func datumHash(bsonData bson.M) (string, error) { + identityFields := []string{} + var datumType string + var errorDebug = func(err error) (string, error) { + log.Printf("error [%s] creating hash for datum %v", err, bsonData) + return "", err + } + datumType, err := GetValidatedString(bsonData, "type") if err != nil { - log.Printf("invalid data type: %#v", bsonData) - return "", err + return errorDebug(err) } - identityFields := []string{} switch datumType { case basal.Type: var basalDatum *basal.Basal - bsonBytes, err := bson.Marshal(bsonData) + dataBytes, err := bson.Marshal(bsonData) if err != nil { - return "", err + return errorDebug(err) } - bson.Unmarshal(bsonBytes, &basalDatum) + bson.Unmarshal(dataBytes, &basalDatum) identityFields, err = basalDatum.IdentityFields() if err != nil { - return "", err + return errorDebug(err) } case bolus.Type: var bolusDatum *bolus.Bolus - bsonBytes, err := bson.Marshal(bsonData) + dataBytes, err := bson.Marshal(bsonData) if err != nil { - return "", err + return errorDebug(err) } - bson.Unmarshal(bsonBytes, &bolusDatum) + bson.Unmarshal(dataBytes, &bolusDatum) identityFields, err = bolusDatum.IdentityFields() if err != nil { - return "", err + return errorDebug(err) } case device.Type: var deviceDatum *device.Device - bsonBytes, err := bson.Marshal(bsonData) + dataBytes, err := bson.Marshal(bsonData) if err != nil { - return "", err + return errorDebug(err) } - bson.Unmarshal(bsonBytes, &deviceDatum) + bson.Unmarshal(dataBytes, &deviceDatum) identityFields, err = deviceDatum.IdentityFields() if err != nil { - return "", err + return errorDebug(err) } case selfmonitored.Type: var smbgDatum *selfmonitored.SelfMonitored - bsonBytes, err := bson.Marshal(bsonData) + dataBytes, err := bson.Marshal(bsonData) if err != nil { - return "", err + return errorDebug(err) } - bson.Unmarshal(bsonBytes, &smbgDatum) + bson.Unmarshal(dataBytes, &smbgDatum) if *smbgDatum.Units != glucose.MgdL && *smbgDatum.Units != glucose.Mgdl { // NOTE: we need to ensure the same precision for the // converted value as it is used to calculate the hash @@ -172,15 +177,15 @@ func datumHash(bsonData bson.M) (string, error) { } identityFields, err = smbgDatum.IdentityFields() if err != nil { - return "", err + return errorDebug(err) } case ketone.Type: var ketoneDatum *ketone.Ketone - bsonBytes, err := bson.Marshal(bsonData) + dataBytes, err := bson.Marshal(bsonData) if err != nil { - return "", err + return errorDebug(err) } - bson.Unmarshal(bsonBytes, &ketoneDatum) + bson.Unmarshal(dataBytes, &ketoneDatum) if *ketoneDatum.Units != glucose.MgdL && *ketoneDatum.Units != glucose.Mgdl { // NOTE: we need to ensure the same precision for the // converted value as it is used to calculate the hash @@ -190,15 +195,15 @@ func datumHash(bsonData bson.M) (string, error) { identityFields, err = ketoneDatum.IdentityFields() if err != nil { - return "", err + return errorDebug(err) } case continuous.Type: var cbgDatum *continuous.Continuous - bsonBytes, err := bson.Marshal(bsonData) + dataBytes, err := bson.Marshal(bsonData) if err != nil { - return "", err + return errorDebug(err) } - bson.Unmarshal(bsonBytes, &cbgDatum) + bson.Unmarshal(dataBytes, &cbgDatum) if *cbgDatum.Units != glucose.MgdL && *cbgDatum.Units != glucose.Mgdl { // NOTE: we need to ensure the same precision for the @@ -209,7 +214,7 @@ func datumHash(bsonData bson.M) (string, error) { identityFields, err = cbgDatum.IdentityFields() if err != nil { - return "", err + return errorDebug(err) } } From 3281648df5117c632919419f1f57321184f677a1 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 13 Dec 2023 17:23:32 +1300 Subject: [PATCH 039/413] error when no id fields --- migrations/20231128_jellyfish_migration/utils/utils.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 015419f45e..6004db0f2d 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -216,7 +216,9 @@ func datumHash(bsonData bson.M) (string, error) { if err != nil { return errorDebug(err) } - + } + if len(identityFields) == 0 { + return errorDebug(errors.New("missing identity fields")) } return deduplicator.GenerateIdentityHash(identityFields) } From 9c077b4cb581c825e81dc73e5ade1bfecb5a4420 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 14 Dec 2023 08:09:09 +1300 Subject: [PATCH 040/413] include calculator type --- .../20231128_jellyfish_migration/utils/utils.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 6004db0f2d..31a79ebe97 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -19,9 +19,11 @@ import ( "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" "github.com/tidepool-org/platform/data/types/blood/ketone" "github.com/tidepool-org/platform/data/types/bolus" + "github.com/tidepool-org/platform/data/types/calculator" "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/data/types/device" "github.com/tidepool-org/platform/data/types/settings/pump" + "github.com/tidepool-org/platform/errors" ) @@ -216,6 +218,17 @@ func datumHash(bsonData bson.M) (string, error) { if err != nil { return errorDebug(err) } + case calculator.Type: + var calcDatum *calculator.Calculator + dataBytes, err := bson.Marshal(bsonData) + if err != nil { + return errorDebug(err) + } + bson.Unmarshal(dataBytes, &calcDatum) + identityFields, err = calcDatum.IdentityFields() + if err != nil { + return errorDebug(err) + } } if len(identityFields) == 0 { return errorDebug(errors.New("missing identity fields")) From f1b9f9a3ae26711f49d2ae0abc3d616328b4bfbb Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 14 Dec 2023 11:23:27 +1300 Subject: [PATCH 041/413] rework to use data types --- .../20231128_jellyfish_migration.go | 12 +- .../utils/utils.go | 310 +++++++----------- 2 files changed, 114 insertions(+), 208 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 528cd35e0c..688e6103c1 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -356,13 +356,11 @@ func (m *Migration) fetchAndUpdateBatch() bool { } m.updates = []mongo.WriteModel{} - sLimit := int64(5) //Testing only get small group at a time if dataC := m.getDataCollection(); dataC != nil { dDataCursor, err := dataC.Find(m.ctx, selector, - //&options.FindOptions{Limit: &m.config.readBatchSize}, &options.FindOptions{ - Limit: &sLimit, + Limit: &m.config.readBatchSize, Sort: bson.M{"_id": 1}, }, ) @@ -379,13 +377,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { return false } - datumID, err := utils.GetValidatedString(dDataResult, "_id") - if err != nil { - log.Printf("failed getting dutum _id: %s", err) - return false - } - - updates, err := utils.GetDatumUpdates(dDataResult) + datumID, updates, err := utils.GetDatumUpdates(dDataResult) if err != nil { log.Printf("failed getting datum updates: %s", err) return false diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 31a79ebe97..5bc002fc9a 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -4,9 +4,7 @@ import ( "fmt" "log" "slices" - "strconv" "strings" - "time" "go.mongodb.org/mongo-driver/bson" @@ -19,7 +17,6 @@ import ( "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" "github.com/tidepool-org/platform/data/types/blood/ketone" "github.com/tidepool-org/platform/data/types/bolus" - "github.com/tidepool-org/platform/data/types/calculator" "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/data/types/device" "github.com/tidepool-org/platform/data/types/settings/pump" @@ -39,90 +36,58 @@ func GetValidatedString(bsonData bson.M, fieldName string) (string, error) { } } -func getValidatedTime(bsonData bson.M, fieldName string) (string, error) { - if valRaw, ok := bsonData[fieldName]; !ok { - return "", errors.Newf("%s is missing", fieldName) - } else if ms, ok := valRaw.(int64); !ok { - if t := time.UnixMilli(ms); !t.IsZero() { - return t.Format(types.TimeFormat), nil +func updateIfExistsPumpSettingsSleepSchedules(datum *pump.Pump) (*pump.SleepScheduleMap, error) { + sleepSchedules := datum.SleepSchedules + if sleepSchedules == nil { + return nil, nil + } + for key := range *sleepSchedules { + days := (*sleepSchedules)[key].Days + updatedDays := []string{} + for _, day := range *days { + if !slices.Contains(common.DaysOfWeek(), strings.ToLower(day)) { + return nil, errors.Newf("pumpSettings.sleepSchedules has an invalid day of week %s", day) + } + updatedDays = append(updatedDays, strings.ToLower(day)) } + (*sleepSchedules)[key].Days = &updatedDays } - log.Printf("invalid data %#v", bsonData) - return "", errors.Newf("%s is missing", fieldName) -} + //sorts schedules based on day + sleepSchedules.Normalize(normalizer.New()) + return sleepSchedules, nil -func datumHash_1(bsonData bson.M) (string, error) { +} - identityFields := []string{} - if datumUserID, err := GetValidatedString(bsonData, "_userId"); err != nil { - log.Printf("invalid data _userId: %#v", bsonData) - return "", err - } else { - identityFields = append(identityFields, datumUserID) +func updateIfExistsPumpSettingsBolus(datum *pump.Pump) (*pump.BolusMap, error) { + bolus := datum.Bolus + if bolus == nil { + return nil, nil } - if deviceID, err := GetValidatedString(bsonData, "deviceId"); err != nil { - log.Printf("invalid data deviceId: %#v", bsonData) - return "", err - } else { - identityFields = append(identityFields, deviceID) - } - if datumTime, err := getValidatedTime(bsonData, "time"); err != nil { - log.Printf("invalid data time: %#v", bsonData) - return "", err - } else { - identityFields = append(identityFields, datumTime) - } - datumType, err := GetValidatedString(bsonData, "type") - if err != nil { - log.Printf("invalid data type: %#v", bsonData) - return "", err + boluses := &pump.BolusMap{ + "one": bolus, } - identityFields = append(identityFields, datumType) + return boluses, nil - switch datumType { - case basal.Type: - if deliveryType, err := GetValidatedString(bsonData, "deliveryType"); err != nil { - return "", err - } else { - identityFields = append(identityFields, deliveryType) - } - case bolus.Type, device.Type: - if subType, err := GetValidatedString(bsonData, "subType"); err != nil { - return "", err - } else { - identityFields = append(identityFields, subType) - } - case selfmonitored.Type, ketone.Type, continuous.Type: - units, err := GetValidatedString(bsonData, "units") - if err != nil { - return "", err - } else { - identityFields = append(identityFields, units) - } +} - if valueRaw, ok := bsonData["value"]; !ok { - return "", errors.New("value is missing") - } else if val, ok := valueRaw.(float64); !ok { - return "", errors.New("value is not of expected type") - } else { - if units != glucose.MgdL && units != glucose.Mgdl { - // NOTE: we need to ensure the same precision for the - // converted value as it is used to calculate the hash - val = GetBGValuePlatformPrecision(val) - } - identityFields = append(identityFields, strconv.FormatFloat(val, 'f', -1, 64)) - } +func GetBGValuePlatformPrecision(mmolVal float64) float64 { + if len(fmt.Sprintf("%v", mmolVal)) > 7 { + mgdlVal := mmolVal * glucose.MmolLToMgdLConversionFactor + mgdL := glucose.MgdL + mmolVal = *glucose.NormalizeValueForUnits(&mgdlVal, &mgdL) } - return deduplicator.GenerateIdentityHash(identityFields) + return mmolVal } -func datumHash(bsonData bson.M) (string, error) { +func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { + updates := bson.M{} + datumID := "" + var identityFields []string - identityFields := []string{} - var datumType string - var errorDebug = func(err error) (string, error) { - log.Printf("error [%s] creating hash for datum %v", err, bsonData) - return "", err + // while doing test runs + var errorDebug = func(err error) (string, bson.M, error) { + log.Printf("[%s] error [%s] creating hash for datum %v", datumID, err, bsonData) + return datumID, nil, err } datumType, err := GetValidatedString(bsonData, "type") @@ -130,191 +95,140 @@ func datumHash(bsonData bson.M) (string, error) { return errorDebug(err) } + dataBytes, err := bson.Marshal(bsonData) + if err != nil { + return errorDebug(err) + } + switch datumType { case basal.Type: - var basalDatum *basal.Basal - dataBytes, err := bson.Marshal(bsonData) + var datum *basal.Basal + err = bson.Unmarshal(dataBytes, &datum) if err != nil { return errorDebug(err) } - bson.Unmarshal(dataBytes, &basalDatum) - identityFields, err = basalDatum.IdentityFields() + datumID = *datum.ID + identityFields, err = datum.IdentityFields() if err != nil { return errorDebug(err) } case bolus.Type: - var bolusDatum *bolus.Bolus - dataBytes, err := bson.Marshal(bsonData) + var datum *bolus.Bolus + err = bson.Unmarshal(dataBytes, &datum) if err != nil { return errorDebug(err) } - bson.Unmarshal(dataBytes, &bolusDatum) - identityFields, err = bolusDatum.IdentityFields() + datumID = *datum.ID + identityFields, err = datum.IdentityFields() if err != nil { return errorDebug(err) } case device.Type: - var deviceDatum *device.Device - dataBytes, err := bson.Marshal(bsonData) + var datum *bolus.Bolus + err = bson.Unmarshal(dataBytes, &datum) + if err != nil { + return errorDebug(err) + } + datumID = *datum.ID + identityFields, err = datum.IdentityFields() + if err != nil { + return errorDebug(err) + } + case pump.Type: + var datum *pump.Pump + err = bson.Unmarshal(dataBytes, &datum) + if err != nil { + return errorDebug(err) + } + datumID = *datum.ID + identityFields, err = datum.IdentityFields() + if err != nil { + return errorDebug(err) + } + + boluses, err := updateIfExistsPumpSettingsBolus(datum) if err != nil { return errorDebug(err) + } else if boluses != nil { + updates["boluses"] = boluses } - bson.Unmarshal(dataBytes, &deviceDatum) - identityFields, err = deviceDatum.IdentityFields() + + sleepSchedules, err := updateIfExistsPumpSettingsSleepSchedules(datum) if err != nil { return errorDebug(err) + } else if sleepSchedules != nil { + updates["sleepSchedules"] = sleepSchedules } + case selfmonitored.Type: - var smbgDatum *selfmonitored.SelfMonitored - dataBytes, err := bson.Marshal(bsonData) + var datum *selfmonitored.SelfMonitored + err = bson.Unmarshal(dataBytes, &datum) if err != nil { return errorDebug(err) } - bson.Unmarshal(dataBytes, &smbgDatum) - if *smbgDatum.Units != glucose.MgdL && *smbgDatum.Units != glucose.Mgdl { + datumID = *datum.ID + if *datum.Units != glucose.MgdL && *datum.Units != glucose.Mgdl { // NOTE: we need to ensure the same precision for the // converted value as it is used to calculate the hash - val := GetBGValuePlatformPrecision(*smbgDatum.Value) - smbgDatum.Value = &val + val := GetBGValuePlatformPrecision(*datum.Value) + datum.Value = &val } - identityFields, err = smbgDatum.IdentityFields() + identityFields, err = datum.IdentityFields() if err != nil { return errorDebug(err) } case ketone.Type: - var ketoneDatum *ketone.Ketone - dataBytes, err := bson.Marshal(bsonData) + var datum *ketone.Ketone + err = bson.Unmarshal(dataBytes, &datum) if err != nil { return errorDebug(err) } - bson.Unmarshal(dataBytes, &ketoneDatum) - if *ketoneDatum.Units != glucose.MgdL && *ketoneDatum.Units != glucose.Mgdl { + datumID = *datum.ID + if *datum.Units != glucose.MgdL && *datum.Units != glucose.Mgdl { // NOTE: we need to ensure the same precision for the // converted value as it is used to calculate the hash - val := GetBGValuePlatformPrecision(*ketoneDatum.Value) - ketoneDatum.Value = &val + val := GetBGValuePlatformPrecision(*datum.Value) + datum.Value = &val } - - identityFields, err = ketoneDatum.IdentityFields() + identityFields, err = datum.IdentityFields() if err != nil { return errorDebug(err) } case continuous.Type: - var cbgDatum *continuous.Continuous - dataBytes, err := bson.Marshal(bsonData) + var datum *continuous.Continuous + err = bson.Unmarshal(dataBytes, &datum) if err != nil { return errorDebug(err) } - bson.Unmarshal(dataBytes, &cbgDatum) - - if *cbgDatum.Units != glucose.MgdL && *cbgDatum.Units != glucose.Mgdl { + datumID = *datum.ID + if *datum.Units != glucose.MgdL && *datum.Units != glucose.Mgdl { // NOTE: we need to ensure the same precision for the // converted value as it is used to calculate the hash - val := GetBGValuePlatformPrecision(*cbgDatum.Value) - cbgDatum.Value = &val + val := GetBGValuePlatformPrecision(*datum.Value) + datum.Value = &val } - - identityFields, err = cbgDatum.IdentityFields() + identityFields, err = datum.IdentityFields() if err != nil { return errorDebug(err) } - case calculator.Type: - var calcDatum *calculator.Calculator - dataBytes, err := bson.Marshal(bsonData) + default: + var datum *types.Base + err = bson.Unmarshal(dataBytes, &datum) if err != nil { return errorDebug(err) } - bson.Unmarshal(dataBytes, &calcDatum) - identityFields, err = calcDatum.IdentityFields() + datumID = *datum.ID + identityFields, err = datum.IdentityFields() if err != nil { return errorDebug(err) } } - if len(identityFields) == 0 { - return errorDebug(errors.New("missing identity fields")) - } - return deduplicator.GenerateIdentityHash(identityFields) -} - -func updateIfExistsPumpSettingsSleepSchedules(bsonData bson.M) (*pump.SleepScheduleMap, error) { - dataType, err := GetValidatedString(bsonData, "type") - if err != nil { - return nil, err - } - - if dataType == pump.Type { - if sleepSchedules := bsonData["sleepSchedules"]; sleepSchedules != nil { - schedules, ok := sleepSchedules.(*pump.SleepScheduleMap) - if !ok { - return nil, errors.Newf("pumpSettings.sleepSchedules is not the expected type %s", sleepSchedules) - } - for key := range *schedules { - days := (*schedules)[key].Days - updatedDays := []string{} - for _, day := range *days { - if !slices.Contains(common.DaysOfWeek(), strings.ToLower(day)) { - return nil, errors.Newf("pumpSettings.sleepSchedules has an invalid day of week %s", day) - } - updatedDays = append(updatedDays, strings.ToLower(day)) - } - (*schedules)[key].Days = &updatedDays - } - //sorts schedules based on day - schedules.Normalize(normalizer.New()) - return schedules, nil - } - } - return nil, nil -} -func updateIfExistsPumpSettingsBolus(bsonData bson.M) (*pump.BolusMap, error) { - dataType, err := GetValidatedString(bsonData, "type") + hash, err := deduplicator.GenerateIdentityHash(identityFields) if err != nil { - return nil, err - } - if dataType == pump.Type { - if bolus := bsonData["bolus"]; bolus != nil { - boluses, ok := bolus.(*pump.BolusMap) - if !ok { - return nil, errors.Newf("pumpSettings.bolus is not the expected type %v", bolus) - } - return boluses, nil - } - } - return nil, nil -} - -func GetBGValuePlatformPrecision(mmolVal float64) float64 { - if len(fmt.Sprintf("%v", mmolVal)) > 7 { - mgdlVal := mmolVal * glucose.MmolLToMgdLConversionFactor - mgdL := glucose.MgdL - mmolVal = *glucose.NormalizeValueForUnits(&mgdlVal, &mgdL) - } - return mmolVal -} - -func GetDatumUpdates(bsonData bson.M) (bson.M, error) { - updates := bson.M{} - - hash, err := datumHash(bsonData) - if err != nil { - return nil, err + return errorDebug(err) } updates["_deduplicator"] = bson.M{"hash": hash} - boluses, err := updateIfExistsPumpSettingsBolus(bsonData) - if err != nil { - return nil, err - } else if boluses != nil { - updates["boluses"] = boluses - } - - sleepSchedules, err := updateIfExistsPumpSettingsSleepSchedules(bsonData) - if err != nil { - return nil, err - } else if sleepSchedules != nil { - updates["sleepSchedules"] = sleepSchedules - } - - return updates, nil + return datumID, updates, nil } From 684d7b8074578585dc2cbc913f8146dcaada5a98 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 14 Dec 2023 14:32:47 +1300 Subject: [PATCH 042/413] fix tests --- .../utils/utils.go | 37 +- .../utils/utils_test.go | 329 +++++++++--------- 2 files changed, 186 insertions(+), 180 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 5bc002fc9a..9b1cb85a56 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -24,18 +24,6 @@ import ( "github.com/tidepool-org/platform/errors" ) -func GetValidatedString(bsonData bson.M, fieldName string) (string, error) { - if valRaw, ok := bsonData[fieldName]; !ok { - return "", errors.Newf("%s is missing", fieldName) - } else if val, ok := valRaw.(string); !ok { - return "", errors.Newf("%s is not of expected type", fieldName) - } else if val == "" { - return "", errors.Newf("%s is empty", fieldName) - } else { - return val, nil - } -} - func updateIfExistsPumpSettingsSleepSchedules(datum *pump.Pump) (*pump.SleepScheduleMap, error) { sleepSchedules := datum.SleepSchedules if sleepSchedules == nil { @@ -58,16 +46,15 @@ func updateIfExistsPumpSettingsSleepSchedules(datum *pump.Pump) (*pump.SleepSche } -func updateIfExistsPumpSettingsBolus(datum *pump.Pump) (*pump.BolusMap, error) { - bolus := datum.Bolus - if bolus == nil { - return nil, nil - } - boluses := &pump.BolusMap{ - "one": bolus, +func updateIfExistsPumpSettingsBolus(bsonData bson.M) (*pump.BolusMap, error) { + if bolus := bsonData["bolus"]; bolus != nil { + boluses, ok := bolus.(*pump.BolusMap) + if !ok { + return nil, errors.Newf("data %v is not the expected boluses type", bolus) + } + return boluses, nil } - return boluses, nil - + return nil, nil } func GetBGValuePlatformPrecision(mmolVal float64) float64 { @@ -90,9 +77,9 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return datumID, nil, err } - datumType, err := GetValidatedString(bsonData, "type") - if err != nil { - return errorDebug(err) + datumType, ok := bsonData["type"].(string) + if !ok { + return errorDebug(errors.New("cannot get the datum type")) } dataBytes, err := bson.Marshal(bsonData) @@ -146,7 +133,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorDebug(err) } - boluses, err := updateIfExistsPumpSettingsBolus(datum) + boluses, err := updateIfExistsPumpSettingsBolus(bsonData) if err != nil { return errorDebug(err) } else if boluses != nil { diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index deff2cbfcc..721706aafe 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -9,6 +9,7 @@ import ( "go.mongodb.org/mongo-driver/bson" "github.com/tidepool-org/platform/data/normalizer" + bolusTest "github.com/tidepool-org/platform/data/types/bolus/test" "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/data/types/settings/pump" pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" @@ -31,197 +32,215 @@ var _ = Describe("back-37", func() { }) var _ = Describe("GetDatumUpdates", func() { - var existingDatum bson.M + var existingBolusDatum bson.M + const expectedID = "some-id" + + var getBSONData = func(datum interface{}) bson.M { + var bsonData bson.M + bsonAsByte, _ := bson.Marshal(&datum) + bson.Unmarshal(bsonAsByte, &bsonData) + return bsonData + } BeforeEach(func() { - existingDatum = bson.M{} - existingDatum["_userId"] = "some-user-id" - existingDatum["deviceId"] = "some-device-id" + datum := bolusTest.RandomBolus() + *datum.ID = expectedID + *datum.UserID = "some-user-id" + *datum.DeviceID = "some-device-id" + datum.SubType = "some-subtype" theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") - existingDatum["time"] = theTime - existingDatum["type"] = "bolous" - Expect(existingDatum).ToNot(BeNil()) + *datum.Time = theTime + existingBolusDatum = getBSONData(datum) + Expect(existingBolusDatum).ToNot(BeNil()) }) + Context("_deduplicator hash", func() { DescribeTable("should", - func(getInput func() bson.M, expected bson.M, expectError bool) { + func(getInput func() bson.M, expectedUpdates bson.M, expectError bool) { input := getInput() - actual, err := utils.GetDatumUpdates(input) + actualID, actualUpdates, err := utils.GetDatumUpdates(input) if expectError { Expect(err).ToNot(BeNil()) - Expect(actual).To(BeNil()) + Expect(actualUpdates).To(BeNil()) return } Expect(err).To(BeNil()) - if expected != nil { - Expect(actual).To(Equal(expected)) + if expectedUpdates != nil { + Expect(actualUpdates).To(Equal(expectedUpdates)) + Expect(actualID).To(Equal(expectedID)) } else { - Expect(actual).To(BeNil()) + Expect(actualUpdates).To(BeNil()) } }, Entry("error when missing _userId", func() bson.M { - existingDatum["_userId"] = nil - return existingDatum + existingBolusDatum["_userId"] = nil + return existingBolusDatum }, nil, true), Entry("error when missing deviceId", func() bson.M { - existingDatum["deviceId"] = nil - return existingDatum + existingBolusDatum["deviceId"] = nil + return existingBolusDatum }, nil, true), Entry("error when missing time", func() bson.M { - existingDatum["time"] = nil - return existingDatum + existingBolusDatum["time"] = nil + return existingBolusDatum }, nil, true), Entry("error when missing type", func() bson.M { - existingDatum["type"] = nil - return existingDatum + existingBolusDatum["type"] = nil + return existingBolusDatum }, nil, true), Entry("adds hash when vaild", func() bson.M { - return existingDatum - }, bson.M{"_deduplicator": bson.M{"hash": "fDOlBxqBW5/iv5zV1Rcsawt4wpiSoHdd/yf5WAXW4/c="}}, false), + return existingBolusDatum + }, bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}, false), ) }) - Context("bolus", func() { - var bolusData = &pump.BolusMap{ - "bolus-1": pumpTest.NewRandomBolus(), - "bolus-2": pumpTest.NewRandomBolus(), - } - var bolusDatum bson.M + Context("pumpSettings", func() { - BeforeEach(func() { - bolusDatum = existingDatum - bolusDatum["type"] = "pumpSettings" - bolusDatum["bolus"] = bolusData - }) - - DescribeTable("should", - func(getInput func() bson.M, expected bson.M, expectError bool) { - input := getInput() - actual, err := utils.GetDatumUpdates(input) - if expectError { - Expect(err).ToNot(BeNil()) - Expect(actual).To(BeNil()) - return - } - Expect(err).To(BeNil()) - if expected != nil { - Expect(actual).To(BeEquivalentTo(expected)) - } else { - Expect(actual).To(BeNil()) - } - }, - - Entry("do nothing when wrong type", - func() bson.M { - bolusDatum["type"] = "other" - return bolusDatum - }, - bson.M{"_deduplicator": bson.M{"hash": "eZburze+ZpJwbBfrNLtugyZybLY1WJH22dWAoVBpyvg="}}, - false, - ), - Entry("do nothing when has no bolus", - func() bson.M { - bolusDatum["bolus"] = nil - return bolusDatum - }, - bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}, - false, - ), - Entry("error bolus when invalid", - func() bson.M { - bolusDatum["bolus"] = "wrong" - return bolusDatum - }, - nil, - true, - ), - Entry("add boluses when bolus found", - func() bson.M { - bolusDatum["bolus"] = bolusData - return bolusDatum - }, - bson.M{ - "_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}, - "boluses": bolusData, - }, - false, - ), - ) - }) - Context("sleepSchedules", func() { - var sleepSchedulesExpected *pump.SleepScheduleMap - var sleepSchedulesStored *pump.SleepScheduleMap - var sleepSchedulesInvalidDays *pump.SleepScheduleMap - var sleepSchedulesDatum bson.M + var pumpSettingsDatum *pump.Pump BeforeEach(func() { + mmolL := pump.DisplayBloodGlucoseUnitsMmolPerL + pumpSettingsDatum = pumpTest.NewPump(&mmolL) + *pumpSettingsDatum.ID = expectedID + *pumpSettingsDatum.UserID = "some-user-id" + *pumpSettingsDatum.DeviceID = "some-device-id" + theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") + *pumpSettingsDatum.Time = theTime + }) - sleepSchedulesDatum = existingDatum - sleepSchedulesDatum["type"] = "pumpSettings" - sleepSchedulesExpected = &pump.SleepScheduleMap{ - "schedule-1": pumpTest.RandomSleepSchedule(), - "schedule-2": pumpTest.RandomSleepSchedule(), - } - sleepSchedulesInvalidDays = pumpTest.CloneSleepSchedules(sleepSchedulesExpected) - (*sleepSchedulesInvalidDays)["schedule-2"].Days = &[]string{"not-a-day", common.DayFriday} - - sleepSchedulesStored = pumpTest.CloneSleepSchedules(sleepSchedulesExpected) - - s1Days := (*sleepSchedulesStored)["schedule-1"].Days - for key, day := range *s1Days { - (*s1Days)[key] = strings.ToUpper(day) + Context("with incorrect jellyfish bolus", func() { + var bolusData = &pump.BolusMap{ + "bolus-1": pumpTest.NewRandomBolus(), + "bolus-2": pumpTest.NewRandomBolus(), } - (*sleepSchedulesStored)["schedule-1"].Days = s1Days + var settingsBolusDatum bson.M + + BeforeEach(func() { + settingsBolusDatum = getBSONData(pumpSettingsDatum) + //as currently set in jellyfish + settingsBolusDatum["bolus"] = bolusData + }) + + DescribeTable("should", + func(getInput func() bson.M, expected bson.M, expectError bool) { + input := getInput() + _, actual, err := utils.GetDatumUpdates(input) + if expectError { + Expect(err).ToNot(BeNil()) + Expect(actual).To(BeNil()) + return + } + Expect(err).To(BeNil()) + if expected != nil { + Expect(actual).To(BeEquivalentTo(expected)) + } else { + Expect(actual).To(BeNil()) + } + }, - s2Days := (*sleepSchedulesStored)["schedule-2"].Days - for key, day := range *s2Days { - (*s2Days)[key] = strings.ToUpper(day) - } - (*sleepSchedulesStored)["schedule-2"].Days = s2Days + Entry("do nothing when wrong type", + func() bson.M { + return existingBolusDatum + }, + bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}, + false, + ), + Entry("do nothing when has no bolus", + func() bson.M { + settingsBolusDatum["bolus"] = nil + return settingsBolusDatum + }, + bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}, + false, + ), + Entry("error bolus when invalid", + func() bson.M { + settingsBolusDatum["bolus"] = "wrong" + return settingsBolusDatum + }, + nil, + true, + ), + Entry("add boluses when bolus found", + func() bson.M { + settingsBolusDatum["bolus"] = bolusData + return settingsBolusDatum + }, + bson.M{ + "_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}, + "boluses": bolusData, + }, + false, + ), + ) + }) + Context("unordered sleepSchedules", func() { + var sleepSchedulesExpected *pump.SleepScheduleMap + var sleepSchedulesStored *pump.SleepScheduleMap + var sleepSchedulesInvalidDays *pump.SleepScheduleMap + var sleepSchedulesDatum bson.M + + BeforeEach(func() { + sleepSchedulesExpected = &pump.SleepScheduleMap{ + "schedule-1": pumpTest.RandomSleepSchedule(), + "schedule-2": pumpTest.RandomSleepSchedule(), + } + sleepSchedulesInvalidDays = pumpTest.CloneSleepSchedules(sleepSchedulesExpected) + (*sleepSchedulesInvalidDays)["schedule-2"].Days = &[]string{"not-a-day", common.DayFriday} - //ensure sorting - sleepSchedulesExpected.Normalize(normalizer.New()) + sleepSchedulesStored = pumpTest.CloneSleepSchedules(sleepSchedulesExpected) - Expect(sleepSchedulesExpected).ToNot(BeNil()) - Expect(sleepSchedulesStored).ToNot(BeNil()) - Expect(sleepSchedulesExpected).ToNot(Equal(sleepSchedulesStored)) - Expect(sleepSchedulesInvalidDays).ToNot(BeNil()) - }) + s1Days := (*sleepSchedulesStored)["schedule-1"].Days + for key, day := range *s1Days { + (*s1Days)[key] = strings.ToUpper(day) + } + (*sleepSchedulesStored)["schedule-1"].Days = s1Days - It("does nothing when wrong type", func() { - sleepSchedulesDatum["type"] = "other" - actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) - Expect(err).To(BeNil()) - Expect(actual).To(Equal(bson.M{"_deduplicator": bson.M{"hash": "eZburze+ZpJwbBfrNLtugyZybLY1WJH22dWAoVBpyvg="}})) - }) - It("does nothing when no sleepSchedules", func() { - sleepSchedulesDatum["sleepSchedules"] = nil - actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) - Expect(err).To(BeNil()) - Expect(actual).To(Equal(bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}})) - }) - It("returns error when sleepSchedules is invalid", func() { - sleepSchedulesDatum["sleepSchedules"] = "wrong" - actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) - Expect(err).ToNot(BeNil()) - Expect(err.Error()).To(Equal("pumpSettings.sleepSchedules is not the expected type wrong")) - Expect(actual).To(BeNil()) - }) - It("returns updated sleepSchedules when valid", func() { - Expect(sleepSchedulesExpected).ToNot(Equal(sleepSchedulesStored)) - sleepSchedulesDatum["sleepSchedules"] = sleepSchedulesStored - actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) - Expect(err).To(BeNil()) - Expect(actual).ToNot(BeNil()) - Expect(actual["sleepSchedules"]).ToNot(BeNil()) - Expect(actual["sleepSchedules"]).To(Equal(sleepSchedulesExpected)) - }) - It("returns error when sleepSchedules have invalid days", func() { - sleepSchedulesDatum["sleepSchedules"] = sleepSchedulesInvalidDays - actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) - Expect(err).ToNot(BeNil()) - Expect(err.Error()).To(Equal("pumpSettings.sleepSchedules has an invalid day of week not-a-day")) - Expect(actual).To(BeNil()) + s2Days := (*sleepSchedulesStored)["schedule-2"].Days + for key, day := range *s2Days { + (*s2Days)[key] = strings.ToUpper(day) + } + (*sleepSchedulesStored)["schedule-2"].Days = s2Days + + //ensure sorting + sleepSchedulesExpected.Normalize(normalizer.New()) + + Expect(sleepSchedulesExpected).ToNot(BeNil()) + Expect(sleepSchedulesStored).ToNot(BeNil()) + Expect(sleepSchedulesExpected).ToNot(Equal(sleepSchedulesStored)) + Expect(sleepSchedulesInvalidDays).ToNot(BeNil()) + pumpSettingsDatum.SleepSchedules = sleepSchedulesStored + sleepSchedulesDatum = getBSONData(pumpSettingsDatum) + sleepSchedulesDatum["bolus"] = nil //remove as not testng here + }) + + It("does nothing when wrong type", func() { + _, actual, err := utils.GetDatumUpdates(existingBolusDatum) + Expect(err).To(BeNil()) + Expect(actual).To(Equal(bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}})) + }) + It("does nothing when no sleepSchedules", func() { + sleepSchedulesDatum["sleepSchedules"] = nil + _, actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) + Expect(err).To(BeNil()) + Expect(actual).To(Equal(bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}})) + }) + It("returns updated sleepSchedules when valid", func() { + Expect(sleepSchedulesExpected).ToNot(Equal(sleepSchedulesStored)) + sleepSchedulesDatum["sleepSchedules"] = sleepSchedulesStored + _, actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) + Expect(err).To(BeNil()) + Expect(actual).ToNot(BeNil()) + Expect(actual["sleepSchedules"]).ToNot(BeNil()) + Expect(actual["sleepSchedules"]).To(Equal(sleepSchedulesExpected)) + }) + It("returns error when sleepSchedules have invalid days", func() { + sleepSchedulesDatum["sleepSchedules"] = sleepSchedulesInvalidDays + _, actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(Equal("pumpSettings.sleepSchedules has an invalid day of week not-a-day")) + Expect(actual).To(BeNil()) + }) }) }) }) From 9cf31b338a9c9621fb796e5122ff53db25156875 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 14 Dec 2023 14:39:14 +1300 Subject: [PATCH 043/413] start processing --- .../20231128_jellyfish_migration.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 688e6103c1..3d35b97efb 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -118,7 +118,7 @@ func (m *Migration) Initialize() error { Name: "batch-size", Usage: "number of records to read each time", Destination: &m.config.readBatchSize, - Value: 10, + Value: 300, Required: false, }, cli.IntFlag{ @@ -183,7 +183,7 @@ func (m *Migration) prepare() error { func (m *Migration) execute() error { totalMigrated := 0 - testingCapSize := 20 + testingCapSize := 1000 for m.fetchAndUpdateBatch() { updatedCount, err := m.writeBatchUpdates() if err != nil { @@ -426,7 +426,7 @@ func (m *Migration) writeBatchUpdates() (int, error) { log.Printf("updates to write %d", len(batch)) updateCount += len(batch) - m.dryRun = true + //m.dryRun = true if !m.dryRun { if deviceC := m.getDataCollection(); deviceC != nil { From f3eecc942cfdfe35c934f698385615688cc57f66 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 14 Dec 2023 15:19:50 +1300 Subject: [PATCH 044/413] remove cap --- .../20231128_jellyfish_migration.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 3d35b97efb..d08936d30b 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -183,7 +183,7 @@ func (m *Migration) prepare() error { func (m *Migration) execute() error { totalMigrated := 0 - testingCapSize := 1000 + //testingCapSize := 1000 for m.fetchAndUpdateBatch() { updatedCount, err := m.writeBatchUpdates() if err != nil { @@ -192,10 +192,10 @@ func (m *Migration) execute() error { } totalMigrated = totalMigrated + updatedCount log.Printf("migrated %d for a total of %d migrated items", updatedCount, totalMigrated) - if totalMigrated >= testingCapSize { - log.Println("migrated docs up to cap so exiting") - break - } + // if totalMigrated >= testingCapSize { + // log.Println("migrated docs up to cap so exiting") + // break + // } } return nil } From 88d3772528d63bed641373c49042587d651ced84 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 15 Dec 2023 08:31:37 +1300 Subject: [PATCH 045/413] debug and dry run enabled --- .../20231128_jellyfish_migration.go | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index d08936d30b..ab1e9d88aa 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -63,7 +63,6 @@ func NewMigration(ctx context.Context) *Migration { cli: cli.NewApp(), config: &Config{}, updates: []mongo.WriteModel{}, - dryRun: true, } } @@ -132,12 +131,12 @@ func (m *Migration) Initialize() error { Name: "nop-percent", Usage: "how much of the oplog is NOP", Destination: &m.config.nopPercent, - Value: 100, + Value: 50, Required: false, }, cli.IntFlag{ Name: "oplog-entry-size", - Usage: "minimum free disk space percent", + Usage: "expected oplog entry size", Destination: &m.config.expectedOplogEntrySize, Value: 420, Required: false, @@ -154,7 +153,8 @@ func (m *Migration) Initialize() error { Usage: "mongo connection URI", Destination: &m.config.uri, Required: false, - FilePath: "./uri", + //uri string comes from file called `uri` + FilePath: "./uri", }, ) return nil @@ -183,7 +183,7 @@ func (m *Migration) prepare() error { func (m *Migration) execute() error { totalMigrated := 0 - //testingCapSize := 1000 + testingCapSize := 300 for m.fetchAndUpdateBatch() { updatedCount, err := m.writeBatchUpdates() if err != nil { @@ -192,10 +192,10 @@ func (m *Migration) execute() error { } totalMigrated = totalMigrated + updatedCount log.Printf("migrated %d for a total of %d migrated items", updatedCount, totalMigrated) - // if totalMigrated >= testingCapSize { - // log.Println("migrated docs up to cap so exiting") - // break - // } + if totalMigrated >= testingCapSize { + log.Printf("migrated %d docs up to cap so exiting", totalMigrated) + break + } } return nil } @@ -354,6 +354,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { } else { selector["_id"] = bson.M{"$not": bson.M{"$type": "objectId"}} } + log.Printf("selector: %#v", selector) m.updates = []mongo.WriteModel{} @@ -383,7 +384,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { return false } - log.Printf("[id=%s] [%v]", datumID, updates) + //log.Printf("[id=%s] [%v]", datumID, updates) m.updates = append(m.updates, mongo.NewUpdateOneModel().SetFilter( bson.M{ @@ -425,20 +426,20 @@ func (m *Migration) writeBatchUpdates() (int, error) { } log.Printf("updates to write %d", len(batch)) - updateCount += len(batch) - //m.dryRun = true - - if !m.dryRun { - if deviceC := m.getDataCollection(); deviceC != nil { - results, err := deviceC.BulkWrite(m.ctx, batch) - if err != nil { - log.Printf("error writing batch updates %v", err) - return updateCount, err - } - updateCount = updateCount + int(results.ModifiedCount) - } + if m.dryRun { + updateCount += len(batch) + log.Println("dry run so not applying changes") + continue } + if deviceC := m.getDataCollection(); deviceC != nil { + results, err := deviceC.BulkWrite(m.ctx, batch) + if err != nil { + log.Printf("error writing batch updates %v", err) + return updateCount, err + } + updateCount = updateCount + int(results.ModifiedCount) + } } log.Printf("applied %d updates", updateCount) return updateCount, nil From 49157ada183b5ef174031e15149eb88718594aab Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 15 Dec 2023 09:10:31 +1300 Subject: [PATCH 046/413] counts --- .../20231128_jellyfish_migration.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index ab1e9d88aa..0506d1bc4d 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -340,7 +340,6 @@ func (m *Migration) blockUntilDBReady() error { func (m *Migration) fetchAndUpdateBatch() bool { selector := bson.M{ - // jellyfish uses a generated _id that is not an mongo objectId "_deduplicator": bson.M{"$exists": false}, // testing based on _userId for jamie+qa3_1@tidepool.org "_userId": "5e8cac61-6bef-4728-b490-c1d82087ed9c", @@ -352,6 +351,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { bson.M{"_id": bson.M{"$not": bson.M{"$type": "objectId"}}}, } } else { + // jellyfish uses a generated _id that is not an mongo objectId selector["_id"] = bson.M{"$not": bson.M{"$type": "objectId"}} } log.Printf("selector: %#v", selector) @@ -438,7 +438,8 @@ func (m *Migration) writeBatchUpdates() (int, error) { log.Printf("error writing batch updates %v", err) return updateCount, err } - updateCount = updateCount + int(results.ModifiedCount) + log.Printf("update results %v", results) + updateCount += int(results.ModifiedCount) } } log.Printf("applied %d updates", updateCount) From 1528ecbfc94f54901f175eb4f1dc23047cdbde90 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 18 Dec 2023 21:56:50 +1300 Subject: [PATCH 047/413] cleanup and debug --- .../20231128_jellyfish_migration.go | 17 ++++++++++------- .../20231128_jellyfish_migration/utils/utils.go | 12 ++++++++++++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 0506d1bc4d..64b47ebe1a 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -230,11 +230,12 @@ func (m *Migration) getOplogDuration() (time.Duration, error) { } -func calculateBatchSize(oplogSize int, oplogEntryBytes int, oplogMinWindow int, nopPercent int) int64 { - return int64(math.Floor(float64(oplogSize) / float64(oplogEntryBytes) / float64(oplogMinWindow) / (float64(nopPercent) / 7))) -} - func (m *Migration) setWriteBatchSize() error { + + var calculateBatchSize = func(oplogSize int, oplogEntryBytes int, oplogMinWindow int, nopPercent int) int64 { + return int64(math.Floor(float64(oplogSize) / float64(oplogEntryBytes) / float64(oplogMinWindow) / (float64(nopPercent) / 7))) + } + if oplogC := m.getOplogCollection(); oplogC != nil { type MongoMetaData struct { MaxSize int `json:"maxSize"` @@ -345,14 +346,16 @@ func (m *Migration) fetchAndUpdateBatch() bool { "_userId": "5e8cac61-6bef-4728-b490-c1d82087ed9c", } + // jellyfish uses a generated _id that is not an mongo objectId + idNotObjectID := bson.M{"$not": bson.M{"$type": "objectId"}} + if m.lastUpdatedId != "" { selector["$and"] = []interface{}{ bson.M{"_id": bson.M{"$gt": m.lastUpdatedId}}, - bson.M{"_id": bson.M{"$not": bson.M{"$type": "objectId"}}}, + bson.M{"_id": idNotObjectID}, } } else { - // jellyfish uses a generated _id that is not an mongo objectId - selector["_id"] = bson.M{"$not": bson.M{"$type": "objectId"}} + selector["_id"] = idNotObjectID } log.Printf("selector: %#v", selector) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 9b1cb85a56..ee56913d4a 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -96,6 +96,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { } datumID = *datum.ID identityFields, err = datum.IdentityFields() + log.Printf("basal %s id %v", datumID, identityFields) if err != nil { return errorDebug(err) } @@ -107,6 +108,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { } datumID = *datum.ID identityFields, err = datum.IdentityFields() + log.Printf("bolus %s id %v", datumID, identityFields) if err != nil { return errorDebug(err) } @@ -118,6 +120,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { } datumID = *datum.ID identityFields, err = datum.IdentityFields() + log.Printf("device %s id %v", datumID, identityFields) if err != nil { return errorDebug(err) } @@ -129,6 +132,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { } datumID = *datum.ID identityFields, err = datum.IdentityFields() + log.Printf("pump %s id %v", datumID, identityFields) if err != nil { return errorDebug(err) } @@ -161,6 +165,8 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { datum.Value = &val } identityFields, err = datum.IdentityFields() + + log.Printf("smbg %s id %v", datumID, identityFields) if err != nil { return errorDebug(err) } @@ -178,6 +184,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { datum.Value = &val } identityFields, err = datum.IdentityFields() + log.Printf("ketone %s id %v", datumID, identityFields) if err != nil { return errorDebug(err) } @@ -195,6 +202,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { datum.Value = &val } identityFields, err = datum.IdentityFields() + log.Printf("cbg %s id %v", datumID, identityFields) if err != nil { return errorDebug(err) } @@ -206,6 +214,8 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { } datumID = *datum.ID identityFields, err = datum.IdentityFields() + + log.Printf("default %s id %v", datumID, identityFields) if err != nil { return errorDebug(err) } @@ -217,5 +227,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { } updates["_deduplicator"] = bson.M{"hash": hash} + log.Printf("datum %s updates %v", datumID, updates) + return datumID, updates, nil } From 1beaf76a59976799e923d093762aae020ace35e3 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 18 Dec 2023 22:08:26 +1300 Subject: [PATCH 048/413] debug for updates --- .../20231128_jellyfish_migration.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 64b47ebe1a..5bd3acc9ac 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -381,20 +381,20 @@ func (m *Migration) fetchAndUpdateBatch() bool { return false } - datumID, updates, err := utils.GetDatumUpdates(dDataResult) + datumID, datumUpdates, err := utils.GetDatumUpdates(dDataResult) if err != nil { log.Printf("failed getting datum updates: %s", err) return false } - //log.Printf("[id=%s] [%v]", datumID, updates) + log.Printf("[id=%s] [%v]", datumID, datumUpdates) m.updates = append(m.updates, mongo.NewUpdateOneModel().SetFilter( bson.M{ "_id": datumID, "modifiedTime": dDataResult["modifiedTime"], }).SetUpdate(bson.M{ - "$set": updates, + "$set": datumUpdates, })) m.lastUpdatedId = datumID } @@ -428,6 +428,7 @@ func (m *Migration) writeBatchUpdates() (int, error) { return updateCount, err } log.Printf("updates to write %d", len(batch)) + log.Printf("first to write %v", batch[0]) if m.dryRun { updateCount += len(batch) From f79a32feb4ed4938a86c20aabb347019d62685a6 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 18 Dec 2023 22:17:42 +1300 Subject: [PATCH 049/413] fix update op --- .../20231128_jellyfish_migration.go | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 5bd3acc9ac..fc29cfd571 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -389,13 +389,10 @@ func (m *Migration) fetchAndUpdateBatch() bool { log.Printf("[id=%s] [%v]", datumID, datumUpdates) - m.updates = append(m.updates, mongo.NewUpdateOneModel().SetFilter( - bson.M{ - "_id": datumID, - "modifiedTime": dDataResult["modifiedTime"], - }).SetUpdate(bson.M{ - "$set": datumUpdates, - })) + updateOp := mongo.NewUpdateOneModel() + updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": dDataResult["modifiedTime"]}) + updateOp.SetUpdate(datumUpdates) + m.updates = append(m.updates, updateOp) m.lastUpdatedId = datumID } return len(m.updates) > 0 From 97216cc095e9ae7485929b2a82f043b2a35a1975 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 18 Dec 2023 22:38:18 +1300 Subject: [PATCH 050/413] bulk options --- .../20231128_jellyfish_migration.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index fc29cfd571..c4b44da3b6 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -391,7 +391,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { updateOp := mongo.NewUpdateOneModel() updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": dDataResult["modifiedTime"]}) - updateOp.SetUpdate(datumUpdates) + updateOp.SetUpdate(bson.M{"$set": datumUpdates}) m.updates = append(m.updates, updateOp) m.lastUpdatedId = datumID } @@ -432,9 +432,11 @@ func (m *Migration) writeBatchUpdates() (int, error) { log.Println("dry run so not applying changes") continue } + bulkOption := options.BulkWriteOptions{} + bulkOption.SetOrdered(true) if deviceC := m.getDataCollection(); deviceC != nil { - results, err := deviceC.BulkWrite(m.ctx, batch) + results, err := deviceC.BulkWrite(m.ctx, batch, &bulkOption) if err != nil { log.Printf("error writing batch updates %v", err) return updateCount, err From 5e1acbe3b025579b6cd4b31e1e2180f921bfde71 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 19 Dec 2023 08:31:28 +1300 Subject: [PATCH 051/413] fix _id --- .../20231128_jellyfish_migration.go | 9 +-- .../utils/utils.go | 63 +++++++++---------- 2 files changed, 32 insertions(+), 40 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index c4b44da3b6..84430b88fe 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -402,7 +402,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { func (m *Migration) writeBatchUpdates() (int, error) { var getBatches = func(chunkSize int) [][]mongo.WriteModel { - log.Printf("updates to apply count: %d", len(m.updates)) + //log.Printf("updates to apply count: %d", len(m.updates)) batches := [][]mongo.WriteModel{} for i := 0; i < len(m.updates); i += chunkSize { end := i + chunkSize @@ -414,7 +414,7 @@ func (m *Migration) writeBatchUpdates() (int, error) { return batches } updateCount := 0 - log.Printf("write batch size %d", *m.writeBatchSize) + //log.Printf("write batch size %d", *m.writeBatchSize) for _, batch := range getBatches(int(*m.writeBatchSize)) { if err := m.blockUntilDBReady(); err != nil { log.Printf("writeBatchUpdates-blocking error: %s", err) @@ -425,18 +425,15 @@ func (m *Migration) writeBatchUpdates() (int, error) { return updateCount, err } log.Printf("updates to write %d", len(batch)) - log.Printf("first to write %v", batch[0]) if m.dryRun { updateCount += len(batch) log.Println("dry run so not applying changes") continue } - bulkOption := options.BulkWriteOptions{} - bulkOption.SetOrdered(true) if deviceC := m.getDataCollection(); deviceC != nil { - results, err := deviceC.BulkWrite(m.ctx, batch, &bulkOption) + results, err := deviceC.BulkWrite(m.ctx, batch) if err != nil { log.Printf("error writing batch updates %v", err) return updateCount, err diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index ee56913d4a..1aa2159ba4 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -68,23 +68,27 @@ func GetBGValuePlatformPrecision(mmolVal float64) float64 { func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { updates := bson.M{} - datumID := "" var identityFields []string // while doing test runs - var errorDebug = func(err error) (string, bson.M, error) { - log.Printf("[%s] error [%s] creating hash for datum %v", datumID, err, bsonData) - return datumID, nil, err + var errorDebug = func(id string, err error) (string, bson.M, error) { + log.Printf("[%s] error [%s] creating hash for datum %v", id, err, bsonData) + return id, nil, err + } + + datumID, ok := bsonData["_id"].(string) + if !ok { + return errorDebug("", errors.New("cannot get the datum id")) } datumType, ok := bsonData["type"].(string) if !ok { - return errorDebug(errors.New("cannot get the datum type")) + return errorDebug(datumID, errors.New("cannot get the datum type")) } dataBytes, err := bson.Marshal(bsonData) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } switch datumType { @@ -92,61 +96,57 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { var datum *basal.Basal err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } - datumID = *datum.ID identityFields, err = datum.IdentityFields() log.Printf("basal %s id %v", datumID, identityFields) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } case bolus.Type: var datum *bolus.Bolus err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } - datumID = *datum.ID identityFields, err = datum.IdentityFields() log.Printf("bolus %s id %v", datumID, identityFields) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } case device.Type: var datum *bolus.Bolus err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } - datumID = *datum.ID identityFields, err = datum.IdentityFields() log.Printf("device %s id %v", datumID, identityFields) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } case pump.Type: var datum *pump.Pump err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } - datumID = *datum.ID identityFields, err = datum.IdentityFields() log.Printf("pump %s id %v", datumID, identityFields) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } boluses, err := updateIfExistsPumpSettingsBolus(bsonData) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } else if boluses != nil { updates["boluses"] = boluses } sleepSchedules, err := updateIfExistsPumpSettingsSleepSchedules(datum) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } else if sleepSchedules != nil { updates["sleepSchedules"] = sleepSchedules } @@ -155,9 +155,8 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { var datum *selfmonitored.SelfMonitored err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } - datumID = *datum.ID if *datum.Units != glucose.MgdL && *datum.Units != glucose.Mgdl { // NOTE: we need to ensure the same precision for the // converted value as it is used to calculate the hash @@ -168,15 +167,14 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { log.Printf("smbg %s id %v", datumID, identityFields) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } case ketone.Type: var datum *ketone.Ketone err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } - datumID = *datum.ID if *datum.Units != glucose.MgdL && *datum.Units != glucose.Mgdl { // NOTE: we need to ensure the same precision for the // converted value as it is used to calculate the hash @@ -186,15 +184,14 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { identityFields, err = datum.IdentityFields() log.Printf("ketone %s id %v", datumID, identityFields) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } case continuous.Type: var datum *continuous.Continuous err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } - datumID = *datum.ID if *datum.Units != glucose.MgdL && *datum.Units != glucose.Mgdl { // NOTE: we need to ensure the same precision for the // converted value as it is used to calculate the hash @@ -204,26 +201,24 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { identityFields, err = datum.IdentityFields() log.Printf("cbg %s id %v", datumID, identityFields) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } default: var datum *types.Base err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } - datumID = *datum.ID identityFields, err = datum.IdentityFields() - log.Printf("default %s id %v", datumID, identityFields) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } } hash, err := deduplicator.GenerateIdentityHash(identityFields) if err != nil { - return errorDebug(err) + return errorDebug(datumID, err) } updates["_deduplicator"] = bson.M{"hash": hash} From 0364865c25402c53fa62baeca89bf2d45283fc34 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 19 Dec 2023 09:02:42 +1300 Subject: [PATCH 052/413] remove testing cap --- .../20231128_jellyfish_migration.go | 10 +++++----- .../20231128_jellyfish_migration/utils/utils.go | 12 ------------ 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 84430b88fe..cec3005767 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -183,7 +183,7 @@ func (m *Migration) prepare() error { func (m *Migration) execute() error { totalMigrated := 0 - testingCapSize := 300 + //testingCapSize := 300 for m.fetchAndUpdateBatch() { updatedCount, err := m.writeBatchUpdates() if err != nil { @@ -192,10 +192,10 @@ func (m *Migration) execute() error { } totalMigrated = totalMigrated + updatedCount log.Printf("migrated %d for a total of %d migrated items", updatedCount, totalMigrated) - if totalMigrated >= testingCapSize { - log.Printf("migrated %d docs up to cap so exiting", totalMigrated) - break - } + // if totalMigrated >= testingCapSize { + // log.Printf("migrated %d docs up to cap so exiting", totalMigrated) + // break + // } } return nil } diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 1aa2159ba4..2bdba5a4fd 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -99,7 +99,6 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorDebug(datumID, err) } identityFields, err = datum.IdentityFields() - log.Printf("basal %s id %v", datumID, identityFields) if err != nil { return errorDebug(datumID, err) } @@ -110,7 +109,6 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorDebug(datumID, err) } identityFields, err = datum.IdentityFields() - log.Printf("bolus %s id %v", datumID, identityFields) if err != nil { return errorDebug(datumID, err) } @@ -121,7 +119,6 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorDebug(datumID, err) } identityFields, err = datum.IdentityFields() - log.Printf("device %s id %v", datumID, identityFields) if err != nil { return errorDebug(datumID, err) } @@ -132,7 +129,6 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorDebug(datumID, err) } identityFields, err = datum.IdentityFields() - log.Printf("pump %s id %v", datumID, identityFields) if err != nil { return errorDebug(datumID, err) } @@ -164,8 +160,6 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { datum.Value = &val } identityFields, err = datum.IdentityFields() - - log.Printf("smbg %s id %v", datumID, identityFields) if err != nil { return errorDebug(datumID, err) } @@ -182,7 +176,6 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { datum.Value = &val } identityFields, err = datum.IdentityFields() - log.Printf("ketone %s id %v", datumID, identityFields) if err != nil { return errorDebug(datumID, err) } @@ -199,7 +192,6 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { datum.Value = &val } identityFields, err = datum.IdentityFields() - log.Printf("cbg %s id %v", datumID, identityFields) if err != nil { return errorDebug(datumID, err) } @@ -210,7 +202,6 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorDebug(datumID, err) } identityFields, err = datum.IdentityFields() - log.Printf("default %s id %v", datumID, identityFields) if err != nil { return errorDebug(datumID, err) } @@ -221,8 +212,5 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorDebug(datumID, err) } updates["_deduplicator"] = bson.M{"hash": hash} - - log.Printf("datum %s updates %v", datumID, updates) - return datumID, updates, nil } From f4652e895b90e616275fe614ff81fb5e8cf945f1 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 19 Dec 2023 13:29:00 +1300 Subject: [PATCH 053/413] debug --- .../20231128_jellyfish_migration.go | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index cec3005767..3364f1db5d 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -78,7 +78,6 @@ func (m *Migration) RunAndExit() { return fmt.Errorf("unable to connect to MongoDB: %w", err) } defer m.client.Disconnect(m.ctx) - log.Printf("config %#v", m.config) if err := m.prepare(); err != nil { log.Printf("prepare failed: %s", err) return err @@ -182,6 +181,9 @@ func (m *Migration) prepare() error { } func (m *Migration) execute() error { + + log.Printf("configured read batch size %d nop percent %d", m.config.readBatchSize, m.config.nopPercent) + totalMigrated := 0 //testingCapSize := 300 for m.fetchAndUpdateBatch() { @@ -357,7 +359,6 @@ func (m *Migration) fetchAndUpdateBatch() bool { } else { selector["_id"] = idNotObjectID } - log.Printf("selector: %#v", selector) m.updates = []mongo.WriteModel{} @@ -387,8 +388,6 @@ func (m *Migration) fetchAndUpdateBatch() bool { return false } - log.Printf("[id=%s] [%v]", datumID, datumUpdates) - updateOp := mongo.NewUpdateOneModel() updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": dDataResult["modifiedTime"]}) updateOp.SetUpdate(bson.M{"$set": datumUpdates}) @@ -402,7 +401,6 @@ func (m *Migration) fetchAndUpdateBatch() bool { func (m *Migration) writeBatchUpdates() (int, error) { var getBatches = func(chunkSize int) [][]mongo.WriteModel { - //log.Printf("updates to apply count: %d", len(m.updates)) batches := [][]mongo.WriteModel{} for i := 0; i < len(m.updates); i += chunkSize { end := i + chunkSize @@ -414,7 +412,6 @@ func (m *Migration) writeBatchUpdates() (int, error) { return batches } updateCount := 0 - //log.Printf("write batch size %d", *m.writeBatchSize) for _, batch := range getBatches(int(*m.writeBatchSize)) { if err := m.blockUntilDBReady(); err != nil { log.Printf("writeBatchUpdates-blocking error: %s", err) @@ -424,7 +421,7 @@ func (m *Migration) writeBatchUpdates() (int, error) { log.Printf("writeBatchUpdates-freespace error: %s", err) return updateCount, err } - log.Printf("updates to write %d", len(batch)) + log.Printf("batch size to write %d", len(batch)) if m.dryRun { updateCount += len(batch) @@ -438,10 +435,8 @@ func (m *Migration) writeBatchUpdates() (int, error) { log.Printf("error writing batch updates %v", err) return updateCount, err } - log.Printf("update results %v", results) updateCount += int(results.ModifiedCount) } } - log.Printf("applied %d updates", updateCount) return updateCount, nil } From 30615406feb2361f12c386355265404f4b96b133 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 19 Dec 2023 19:27:40 +1300 Subject: [PATCH 054/413] sort parsing of pumpSettings sleepSchedules --- .../utils/utils.go | 51 +++++++++------ .../utils/utils_test.go | 65 +++++++++---------- 2 files changed, 60 insertions(+), 56 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 2bdba5a4fd..386170dfaa 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -1,6 +1,7 @@ package utils import ( + "encoding/json" "fmt" "log" "slices" @@ -24,26 +25,37 @@ import ( "github.com/tidepool-org/platform/errors" ) -func updateIfExistsPumpSettingsSleepSchedules(datum *pump.Pump) (*pump.SleepScheduleMap, error) { - sleepSchedules := datum.SleepSchedules - if sleepSchedules == nil { - return nil, nil - } - for key := range *sleepSchedules { - days := (*sleepSchedules)[key].Days - updatedDays := []string{} - for _, day := range *days { - if !slices.Contains(common.DaysOfWeek(), strings.ToLower(day)) { - return nil, errors.Newf("pumpSettings.sleepSchedules has an invalid day of week %s", day) +func updateIfExistsPumpSettingsSleepSchedules(bsonData bson.M) (*pump.SleepScheduleMap, error) { + scheduleNames := map[int]string{0: "One", 1: "Two", 2: "Three", 3: "Four", 4: "Five"} + + if schedules := bsonData["sleepSchedules"]; schedules != nil { + sleepScheduleMap := pump.SleepScheduleMap{} + dataBytes, err := json.Marshal(schedules) + if err != nil { + return nil, err + } + schedulesArray := []*pump.SleepSchedule{} + err = json.Unmarshal(dataBytes, &schedulesArray) + if err != nil { + return nil, err + } + for i, schedule := range schedulesArray { + days := schedule.Days + updatedDays := []string{} + for _, day := range *days { + if !slices.Contains(common.DaysOfWeek(), strings.ToLower(day)) { + return nil, errors.Newf("pumpSettings.sleepSchedules has an invalid day of week %s", day) + } + updatedDays = append(updatedDays, strings.ToLower(day)) } - updatedDays = append(updatedDays, strings.ToLower(day)) + schedule.Days = &updatedDays + sleepScheduleMap[scheduleNames[i]] = schedule } - (*sleepSchedules)[key].Days = &updatedDays + //sorts schedules based on day + sleepScheduleMap.Normalize(normalizer.New()) + return &sleepScheduleMap, nil } - //sorts schedules based on day - sleepSchedules.Normalize(normalizer.New()) - return sleepSchedules, nil - + return nil, nil } func updateIfExistsPumpSettingsBolus(bsonData bson.M) (*pump.BolusMap, error) { @@ -123,7 +135,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorDebug(datumID, err) } case pump.Type: - var datum *pump.Pump + var datum *types.Base err = bson.Unmarshal(dataBytes, &datum) if err != nil { return errorDebug(datumID, err) @@ -140,13 +152,12 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { updates["boluses"] = boluses } - sleepSchedules, err := updateIfExistsPumpSettingsSleepSchedules(datum) + sleepSchedules, err := updateIfExistsPumpSettingsSleepSchedules(bsonData) if err != nil { return errorDebug(datumID, err) } else if sleepSchedules != nil { updates["sleepSchedules"] = sleepSchedules } - case selfmonitored.Type: var datum *selfmonitored.SelfMonitored err = bson.Unmarshal(dataBytes, &datum) diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 721706aafe..8c70df5817 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -51,6 +51,7 @@ var _ = Describe("back-37", func() { theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") *datum.Time = theTime existingBolusDatum = getBSONData(datum) + existingBolusDatum["_id"] = expectedID Expect(existingBolusDatum).ToNot(BeNil()) }) @@ -108,7 +109,7 @@ var _ = Describe("back-37", func() { *pumpSettingsDatum.Time = theTime }) - Context("with incorrect jellyfish bolus", func() { + Context("with mis-named jellyfish bolus", func() { var bolusData = &pump.BolusMap{ "bolus-1": pumpTest.NewRandomBolus(), "bolus-2": pumpTest.NewRandomBolus(), @@ -117,8 +118,8 @@ var _ = Describe("back-37", func() { BeforeEach(func() { settingsBolusDatum = getBSONData(pumpSettingsDatum) - //as currently set in jellyfish settingsBolusDatum["bolus"] = bolusData + settingsBolusDatum["_id"] = expectedID }) DescribeTable("should", @@ -175,43 +176,36 @@ var _ = Describe("back-37", func() { ) }) Context("unordered sleepSchedules", func() { - var sleepSchedulesExpected *pump.SleepScheduleMap - var sleepSchedulesStored *pump.SleepScheduleMap - var sleepSchedulesInvalidDays *pump.SleepScheduleMap + expectedSleepSchedulesMap := &pump.SleepScheduleMap{} + var invalidDays *pump.SleepSchedule + var s1Days *pump.SleepSchedule + var s2Days *pump.SleepSchedule var sleepSchedulesDatum bson.M - BeforeEach(func() { - sleepSchedulesExpected = &pump.SleepScheduleMap{ - "schedule-1": pumpTest.RandomSleepSchedule(), - "schedule-2": pumpTest.RandomSleepSchedule(), + s1 := pumpTest.RandomSleepSchedule() + s2 := pumpTest.RandomSleepSchedule() + (*expectedSleepSchedulesMap)["One"] = s1 + (*expectedSleepSchedulesMap)["Two"] = s2 + + s1Days = pumpTest.CloneSleepSchedule(s1) + for key, day := range *s1Days.Days { + (*s1Days.Days)[key] = strings.ToUpper(day) } - sleepSchedulesInvalidDays = pumpTest.CloneSleepSchedules(sleepSchedulesExpected) - (*sleepSchedulesInvalidDays)["schedule-2"].Days = &[]string{"not-a-day", common.DayFriday} - - sleepSchedulesStored = pumpTest.CloneSleepSchedules(sleepSchedulesExpected) - - s1Days := (*sleepSchedulesStored)["schedule-1"].Days - for key, day := range *s1Days { - (*s1Days)[key] = strings.ToUpper(day) - } - (*sleepSchedulesStored)["schedule-1"].Days = s1Days - - s2Days := (*sleepSchedulesStored)["schedule-2"].Days - for key, day := range *s2Days { - (*s2Days)[key] = strings.ToUpper(day) + s2Days = pumpTest.CloneSleepSchedule(s2) + for key, day := range *s2Days.Days { + (*s2Days.Days)[key] = strings.ToUpper(day) } - (*sleepSchedulesStored)["schedule-2"].Days = s2Days + invalidDays = pumpTest.CloneSleepSchedule(s2) + invalidDays.Days = &[]string{"not-a-day", common.DayFriday} - //ensure sorting - sleepSchedulesExpected.Normalize(normalizer.New()) + //to ensure correct sorting + expectedSleepSchedulesMap.Normalize(normalizer.New()) - Expect(sleepSchedulesExpected).ToNot(BeNil()) - Expect(sleepSchedulesStored).ToNot(BeNil()) - Expect(sleepSchedulesExpected).ToNot(Equal(sleepSchedulesStored)) - Expect(sleepSchedulesInvalidDays).ToNot(BeNil()) - pumpSettingsDatum.SleepSchedules = sleepSchedulesStored + Expect(expectedSleepSchedulesMap).ToNot(BeNil()) + pumpSettingsDatum.SleepSchedules = nil sleepSchedulesDatum = getBSONData(pumpSettingsDatum) - sleepSchedulesDatum["bolus"] = nil //remove as not testng here + sleepSchedulesDatum["_id"] = expectedID + sleepSchedulesDatum["bolus"] = nil //remove as not testing here }) It("does nothing when wrong type", func() { @@ -226,16 +220,15 @@ var _ = Describe("back-37", func() { Expect(actual).To(Equal(bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}})) }) It("returns updated sleepSchedules when valid", func() { - Expect(sleepSchedulesExpected).ToNot(Equal(sleepSchedulesStored)) - sleepSchedulesDatum["sleepSchedules"] = sleepSchedulesStored + sleepSchedulesDatum["sleepSchedules"] = []*pump.SleepSchedule{s1Days, s2Days} _, actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) Expect(err).To(BeNil()) Expect(actual).ToNot(BeNil()) Expect(actual["sleepSchedules"]).ToNot(BeNil()) - Expect(actual["sleepSchedules"]).To(Equal(sleepSchedulesExpected)) + Expect(actual["sleepSchedules"]).To(Equal(expectedSleepSchedulesMap)) }) It("returns error when sleepSchedules have invalid days", func() { - sleepSchedulesDatum["sleepSchedules"] = sleepSchedulesInvalidDays + sleepSchedulesDatum["sleepSchedules"] = []*pump.SleepSchedule{invalidDays} _, actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) Expect(err).ToNot(BeNil()) Expect(err.Error()).To(Equal("pumpSettings.sleepSchedules has an invalid day of week not-a-day")) From e1939df593473ebdd98b45f98030e2efcb7f29ed Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 19 Dec 2023 19:36:16 +1300 Subject: [PATCH 055/413] convert to BolusMap --- .../20231128_jellyfish_migration/utils/utils.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 386170dfaa..c70289b472 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -60,11 +60,16 @@ func updateIfExistsPumpSettingsSleepSchedules(bsonData bson.M) (*pump.SleepSched func updateIfExistsPumpSettingsBolus(bsonData bson.M) (*pump.BolusMap, error) { if bolus := bsonData["bolus"]; bolus != nil { - boluses, ok := bolus.(*pump.BolusMap) - if !ok { - return nil, errors.Newf("data %v is not the expected boluses type", bolus) + boluses := pump.BolusMap{} + dataBytes, err := json.Marshal(bolus) + if err != nil { + return nil, err + } + err = json.Unmarshal(dataBytes, &boluses) + if err != nil { + return nil, err } - return boluses, nil + return &boluses, nil } return nil, nil } From 4144141e6e0c78762ed9d407f075d966f8180e15 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 20 Dec 2023 08:45:16 +1300 Subject: [PATCH 056/413] remove debug --- .../20231128_jellyfish_migration.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 3364f1db5d..564edb48d7 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -181,11 +181,8 @@ func (m *Migration) prepare() error { } func (m *Migration) execute() error { - log.Printf("configured read batch size %d nop percent %d", m.config.readBatchSize, m.config.nopPercent) - totalMigrated := 0 - //testingCapSize := 300 for m.fetchAndUpdateBatch() { updatedCount, err := m.writeBatchUpdates() if err != nil { @@ -194,10 +191,6 @@ func (m *Migration) execute() error { } totalMigrated = totalMigrated + updatedCount log.Printf("migrated %d for a total of %d migrated items", updatedCount, totalMigrated) - // if totalMigrated >= testingCapSize { - // log.Printf("migrated %d docs up to cap so exiting", totalMigrated) - // break - // } } return nil } From 50ca589ad4c36a1f8aebb45e020ae07173a5fccd Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 20 Dec 2023 09:47:57 +1300 Subject: [PATCH 057/413] remove test doc --- .../20231128_jellyfish_migration/test.json | 135 ------------------ 1 file changed, 135 deletions(-) delete mode 100644 migrations/20231128_jellyfish_migration/test.json diff --git a/migrations/20231128_jellyfish_migration/test.json b/migrations/20231128_jellyfish_migration/test.json deleted file mode 100644 index 61c38dc9c1..0000000000 --- a/migrations/20231128_jellyfish_migration/test.json +++ /dev/null @@ -1,135 +0,0 @@ -[ - "006j3omlmfijf7ifks6kkja2kdjjhlsk", - { - "_deduplicator": { "hash": "8cZ6O9FevUGu0UAqWzcpayBEov+R320ERRD/DKCJEQo=" } - }, - { - "_active": true, - "_groupId": "d7762454ad", - "_id": "006j3omlmfijf7ifks6kkja2kdjjhlsk", - "_userId": "5e8cac61-6bef-4728-b490-c1d82087ed9c", - "_version": 0, - "clockDriftOffset": 0, - "conversionOffset": 0, - "createdTime": 1701313771417, - "deliveryType": "automated", - "deviceId": "tandemCIQ10027171066407", - "deviceTime": "2023-10-18T05:21:49", - "duration": 601000, - "guid": "0b9e6f52-8406-4e02-9c9d-fe1704535a73", - "id": "utcutdn65391j2s0nj11ecl9qv8lo7bv", - "modifiedTime": 1701313771417, - "rate": 1.2, - "suppressed": { "deliveryType": "scheduled", "rate": 1.2, "type": "basal" }, - "time": 1697559709000, - "timezoneOffset": 780, - "type": "basal", - "uploadId": "upid_95cb50bf426d" - }, - - "006q5m29ba3ehqm9v8ra9l36rtcdfa4d", - { - "_deduplicator": { "hash": "8cZ6O9FevUGu0UAqWzcpayBEov+R320ERRD/DKCJEQo=" } - }, - { - "_active": true, - "_groupId": "d7762454ad", - "_id": "006q5m29ba3ehqm9v8ra9l36rtcdfa4d", - "_userId": "5e8cac61-6bef-4728-b490-c1d82087ed9c", - "_version": 0, - "clockDriftOffset": -158000, - "conversionOffset": 0, - "createdTime": 1701313654014, - "deliveryType": "automated", - "deviceId": "tandemCIQ10027171066407", - "deviceTime": "2023-09-13T15:27:37", - "duration": 301000, - "guid": "a4ad9653-34b8-48ac-b83f-018b7b6d6b55", - "id": "qijmfaopb2jm5sfkhgm2eogl1vak702u", - "modifiedTime": 1701313654014, - "rate": 0.123, - "suppressed": { "deliveryType": "scheduled", "rate": 0.9, "type": "basal" }, - "time": 1694575657000, - "timezoneOffset": 720, - "type": "basal", - "uploadId": "upid_95cb50bf426d" - }, - "006qgkujndr8854pql2bct8b0s59crrg", - { - "_deduplicator": { "hash": "PJwR47UL7JvZUrqgapgiG8KJhOEdwWWWuaC/SIE/s6M=" } - }, - { - "_active": true, - "_groupId": "d7762454ad", - "_id": "006qgkujndr8854pql2bct8b0s59crrg", - "_userId": "5e8cac61-6bef-4728-b490-c1d82087ed9c", - "_version": 0, - "clockDriftOffset": 0, - "conversionOffset": 0, - "createdTime": 1701313853944, - "deviceId": "tandemCIQ10027171066407", - "deviceTime": "2023-11-13T01:12:30", - "guid": "45b69cb3-6268-4174-90b3-a790665e0acf", - "id": "9i9hsb27i11uirg60safrcfdujugsv0u", - "modifiedTime": 1701313853944, - "rate": -3, - "rssi": -88, - "timestamp": 500692350, - "time": 1699791150000, - "timezoneOffset": 780, - "type": "cbg", - "units": "mmol/L", - "uploadId": "upid_95cb50bf426d", - "value": 5.217703111582802 - }, - "009d3ntunue9ekdpa5sajcm8qnd9mrm2", - { - "_deduplicator": { "hash": "w1DGKyl5uQcvv3mMXG2zN4ifvFU/7t6lAmcgHvjnC6o=" } - }, - { - "_active": true, - "_groupId": "d7762454ad", - "_id": "009d3ntunue9ekdpa5sajcm8qnd9mrm2", - "_userId": "5e8cac61-6bef-4728-b490-c1d82087ed9c", - "_version": 0, - "clockDriftOffset": -158000, - "conversionOffset": 0, - "createdTime": 1701313671438, - "deviceId": "tandemCIQ10027171066407", - "deviceTime": "2023-09-18T12:03:43", - "guid": "a7169991-51c5-46d0-ab93-b663a097759f", - "id": "alrb1615n8eru2r6b0js9077j44tikhq", - "modifiedTime": 1701313671438, - "time": 1694995423000, - "timezoneOffset": 720, - "type": "cbg", - "units": "mmol/L", - "uploadId": "upid_95cb50bf426d", - "value": 9.047719225404219 - }, - "00akqvf80nioro5l9noq1tgvh6srsope", - { - "_deduplicator": { "hash": "3LziAIxBKna0rS9/LSjHRMdy0eJGsFTIsaeVzaPNCEA=" } - }, - { - "_active": true, - "_groupId": "d7762454ad", - "_id": "00akqvf80nioro5l9noq1tgvh6srsope", - "_userId": "5e8cac61-6bef-4728-b490-c1d82087ed9c", - "_version": 0, - "clockDriftOffset": 0, - "conversionOffset": 0, - "createdTime": 1701313762010, - "deviceId": "tandemCIQ10027171066407", - "deviceTime": "2023-10-15T19:00:48", - "guid": "8f52ccf4-ce88-485c-9aa4-fe5cc82f5abb", - "id": "q2fqkdv7h9rolg7u14r16p1fc2cb1vo0", - "modifiedTime": 1701313762010, - "time": 1697349648000, - "timezoneOffset": 780, - "type": "cbg", - "units": "mmol/L", - "uploadId": "upid_95cb50bf426d", - "value": 5.7172704307769 - } -] From d41ccc528fe045275d3c2588f16f5999e9b0ccf9 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 20 Dec 2023 13:04:07 +1300 Subject: [PATCH 058/413] timings and updates based on testing --- .../20231128_jellyfish_migration.go | 23 ++++++++--- .../utils/utils.go | 39 +++++++++---------- .../utils/utils_test.go | 31 ++++++--------- 3 files changed, 48 insertions(+), 45 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 564edb48d7..8a599960a0 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -42,6 +42,7 @@ type Migration struct { writeBatchSize *int64 updates []mongo.WriteModel dryRun bool + stopOnErr bool lastUpdatedId string } @@ -59,10 +60,11 @@ func main() { func NewMigration(ctx context.Context) *Migration { return &Migration{ - ctx: ctx, - cli: cli.NewApp(), - config: &Config{}, - updates: []mongo.WriteModel{}, + ctx: ctx, + cli: cli.NewApp(), + config: &Config{}, + updates: []mongo.WriteModel{}, + stopOnErr: false, } } @@ -112,6 +114,11 @@ func (m *Migration) Initialize() error { Usage: "dry run only; do not migrate", Destination: &m.dryRun, }, + cli.BoolFlag{ + Name: "stop-error", + Usage: "stop migration on error", + Destination: &m.dryRun, + }, cli.Int64Flag{ Name: "batch-size", Usage: "number of records to read each time", @@ -184,6 +191,7 @@ func (m *Migration) execute() error { log.Printf("configured read batch size %d nop percent %d", m.config.readBatchSize, m.config.nopPercent) totalMigrated := 0 for m.fetchAndUpdateBatch() { + updatedCount, err := m.writeBatchUpdates() if err != nil { log.Printf("failed writing batch: %s", err) @@ -335,6 +343,8 @@ func (m *Migration) blockUntilDBReady() error { } func (m *Migration) fetchAndUpdateBatch() bool { + start := time.Now() + selector := bson.M{ "_deduplicator": bson.M{"$exists": false}, // testing based on _userId for jamie+qa3_1@tidepool.org @@ -383,16 +393,18 @@ func (m *Migration) fetchAndUpdateBatch() bool { updateOp := mongo.NewUpdateOneModel() updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": dDataResult["modifiedTime"]}) - updateOp.SetUpdate(bson.M{"$set": datumUpdates}) + updateOp.SetUpdate(datumUpdates) m.updates = append(m.updates, updateOp) m.lastUpdatedId = datumID } + log.Printf("selector took %s", time.Since(start)) return len(m.updates) > 0 } return false } func (m *Migration) writeBatchUpdates() (int, error) { + start := time.Now() var getBatches = func(chunkSize int) [][]mongo.WriteModel { batches := [][]mongo.WriteModel{} for i := 0; i < len(m.updates); i += chunkSize { @@ -431,5 +443,6 @@ func (m *Migration) writeBatchUpdates() (int, error) { updateCount += int(results.ModifiedCount) } } + log.Printf("update took %s", time.Since(start)) return updateCount, nil } diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index c70289b472..2f0c4221f5 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -21,12 +21,12 @@ import ( "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/data/types/device" "github.com/tidepool-org/platform/data/types/settings/pump" - "github.com/tidepool-org/platform/errors" ) func updateIfExistsPumpSettingsSleepSchedules(bsonData bson.M) (*pump.SleepScheduleMap, error) { - scheduleNames := map[int]string{0: "One", 1: "Two", 2: "Three", 3: "Four", 4: "Five"} + //TODO: currently an array but should be a map for consistency. On pump is "Sleep Schedule 1", "Sleep Schedule 2" + scheduleNames := map[int]string{0: "1", 1: "2"} if schedules := bsonData["sleepSchedules"]; schedules != nil { sleepScheduleMap := pump.SleepScheduleMap{} @@ -58,20 +58,13 @@ func updateIfExistsPumpSettingsSleepSchedules(bsonData bson.M) (*pump.SleepSched return nil, nil } -func updateIfExistsPumpSettingsBolus(bsonData bson.M) (*pump.BolusMap, error) { +func pumpSettingsHasBolus(bsonData bson.M) bool { if bolus := bsonData["bolus"]; bolus != nil { - boluses := pump.BolusMap{} - dataBytes, err := json.Marshal(bolus) - if err != nil { - return nil, err - } - err = json.Unmarshal(dataBytes, &boluses) - if err != nil { - return nil, err + if _, ok := bolus.(*pump.BolusMap); ok { + return true } - return &boluses, nil } - return nil, nil + return false } func GetBGValuePlatformPrecision(mmolVal float64) float64 { @@ -84,7 +77,8 @@ func GetBGValuePlatformPrecision(mmolVal float64) float64 { } func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { - updates := bson.M{} + set := bson.M{} + var rename bson.M var identityFields []string // while doing test runs @@ -150,18 +144,15 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorDebug(datumID, err) } - boluses, err := updateIfExistsPumpSettingsBolus(bsonData) - if err != nil { - return errorDebug(datumID, err) - } else if boluses != nil { - updates["boluses"] = boluses + if pumpSettingsHasBolus(bsonData) { + rename = bson.M{"bolus": "boluses"} } sleepSchedules, err := updateIfExistsPumpSettingsSleepSchedules(bsonData) if err != nil { return errorDebug(datumID, err) } else if sleepSchedules != nil { - updates["sleepSchedules"] = sleepSchedules + set["sleepSchedules"] = sleepSchedules } case selfmonitored.Type: var datum *selfmonitored.SelfMonitored @@ -227,6 +218,12 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { if err != nil { return errorDebug(datumID, err) } - updates["_deduplicator"] = bson.M{"hash": hash} + set["_deduplicator"] = bson.M{"hash": hash} + + var updates = bson.M{"$set": set} + if rename != nil { + updates["$rename"] = rename + } + return datumID, updates, nil } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 8c70df5817..012e30d1cc 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -91,7 +91,7 @@ var _ = Describe("back-37", func() { }, nil, true), Entry("adds hash when vaild", func() bson.M { return existingBolusDatum - }, bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}, false), + }, bson.M{"$set": bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}}, false), ) }) @@ -143,7 +143,7 @@ var _ = Describe("back-37", func() { func() bson.M { return existingBolusDatum }, - bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}, + bson.M{"$set": bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}}, false, ), Entry("do nothing when has no bolus", @@ -151,25 +151,17 @@ var _ = Describe("back-37", func() { settingsBolusDatum["bolus"] = nil return settingsBolusDatum }, - bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}, + bson.M{"$set": bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}}, false, ), - Entry("error bolus when invalid", - func() bson.M { - settingsBolusDatum["bolus"] = "wrong" - return settingsBolusDatum - }, - nil, - true, - ), Entry("add boluses when bolus found", func() bson.M { settingsBolusDatum["bolus"] = bolusData return settingsBolusDatum }, bson.M{ - "_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}, - "boluses": bolusData, + "$set": bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}, + "$rename": bson.M{"bolus": "boluses"}, }, false, ), @@ -184,8 +176,8 @@ var _ = Describe("back-37", func() { BeforeEach(func() { s1 := pumpTest.RandomSleepSchedule() s2 := pumpTest.RandomSleepSchedule() - (*expectedSleepSchedulesMap)["One"] = s1 - (*expectedSleepSchedulesMap)["Two"] = s2 + (*expectedSleepSchedulesMap)["1"] = s1 + (*expectedSleepSchedulesMap)["2"] = s2 s1Days = pumpTest.CloneSleepSchedule(s1) for key, day := range *s1Days.Days { @@ -211,21 +203,22 @@ var _ = Describe("back-37", func() { It("does nothing when wrong type", func() { _, actual, err := utils.GetDatumUpdates(existingBolusDatum) Expect(err).To(BeNil()) - Expect(actual).To(Equal(bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}})) + Expect(actual).To(Equal(bson.M{"$set": bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}})) }) It("does nothing when no sleepSchedules", func() { sleepSchedulesDatum["sleepSchedules"] = nil _, actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) Expect(err).To(BeNil()) - Expect(actual).To(Equal(bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}})) + Expect(actual).To(Equal(bson.M{"$set": bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}})) }) It("returns updated sleepSchedules when valid", func() { sleepSchedulesDatum["sleepSchedules"] = []*pump.SleepSchedule{s1Days, s2Days} _, actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) Expect(err).To(BeNil()) Expect(actual).ToNot(BeNil()) - Expect(actual["sleepSchedules"]).ToNot(BeNil()) - Expect(actual["sleepSchedules"]).To(Equal(expectedSleepSchedulesMap)) + setData := actual["$set"].(bson.M) + Expect(setData["sleepSchedules"]).ToNot(BeNil()) + Expect(setData["sleepSchedules"]).To(Equal(expectedSleepSchedulesMap)) }) It("returns error when sleepSchedules have invalid days", func() { sleepSchedulesDatum["sleepSchedules"] = []*pump.SleepSchedule{invalidDays} From 899539b04812d5dd3aaa0c2ea1cb63f860115a11 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 20 Dec 2023 13:59:29 +1300 Subject: [PATCH 059/413] errors either log to file or stop --- .../20231128_jellyfish_migration.go | 23 +++++++-- .../utils/utils.go | 47 +++++++++---------- 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 8a599960a0..dc3e8b8c19 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -117,7 +117,7 @@ func (m *Migration) Initialize() error { cli.BoolFlag{ Name: "stop-error", Usage: "stop migration on error", - Destination: &m.dryRun, + Destination: &m.stopOnErr, }, cli.Int64Flag{ Name: "batch-size", @@ -176,6 +176,23 @@ func (m *Migration) getDataCollection() *mongo.Collection { func (m *Migration) getOplogCollection() *mongo.Collection { return m.client.Database("local").Collection(oplogName) } +func (m *Migration) onError(err error, id string, msg string) { + var errFormat = "[id=%s] %s %s" + if err != nil { + if m.stopOnErr { + log.Printf(errFormat, id, msg, err.Error()) + os.Exit(1) + } + f, err := os.OpenFile("error.log", + os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Println(err) + os.Exit(1) + } + defer f.Close() + f.WriteString(fmt.Sprintf(errFormat, id, msg, err.Error())) + } +} func (m *Migration) prepare() error { if err := m.checkFreeSpace(); err != nil { @@ -387,8 +404,8 @@ func (m *Migration) fetchAndUpdateBatch() bool { datumID, datumUpdates, err := utils.GetDatumUpdates(dDataResult) if err != nil { - log.Printf("failed getting datum updates: %s", err) - return false + m.onError(err, datumID, "failed getting updates") + continue } updateOp := mongo.NewUpdateOneModel() diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 2f0c4221f5..4af333e26c 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -3,7 +3,6 @@ package utils import ( "encoding/json" "fmt" - "log" "slices" "strings" @@ -81,25 +80,23 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { var rename bson.M var identityFields []string - // while doing test runs - var errorDebug = func(id string, err error) (string, bson.M, error) { - log.Printf("[%s] error [%s] creating hash for datum %v", id, err, bsonData) + var errorHandler = func(id string, err error) (string, bson.M, error) { return id, nil, err } datumID, ok := bsonData["_id"].(string) if !ok { - return errorDebug("", errors.New("cannot get the datum id")) + return errorHandler("", errors.New("cannot get the datum id")) } datumType, ok := bsonData["type"].(string) if !ok { - return errorDebug(datumID, errors.New("cannot get the datum type")) + return errorHandler(datumID, errors.New("cannot get the datum type")) } dataBytes, err := bson.Marshal(bsonData) if err != nil { - return errorDebug(datumID, err) + return errorHandler(datumID, err) } switch datumType { @@ -107,41 +104,41 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { var datum *basal.Basal err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorDebug(datumID, err) + return errorHandler(datumID, err) } identityFields, err = datum.IdentityFields() if err != nil { - return errorDebug(datumID, err) + return errorHandler(datumID, err) } case bolus.Type: var datum *bolus.Bolus err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorDebug(datumID, err) + return errorHandler(datumID, err) } identityFields, err = datum.IdentityFields() if err != nil { - return errorDebug(datumID, err) + return errorHandler(datumID, err) } case device.Type: var datum *bolus.Bolus err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorDebug(datumID, err) + return errorHandler(datumID, err) } identityFields, err = datum.IdentityFields() if err != nil { - return errorDebug(datumID, err) + return errorHandler(datumID, err) } case pump.Type: var datum *types.Base err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorDebug(datumID, err) + return errorHandler(datumID, err) } identityFields, err = datum.IdentityFields() if err != nil { - return errorDebug(datumID, err) + return errorHandler(datumID, err) } if pumpSettingsHasBolus(bsonData) { @@ -150,7 +147,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { sleepSchedules, err := updateIfExistsPumpSettingsSleepSchedules(bsonData) if err != nil { - return errorDebug(datumID, err) + return errorHandler(datumID, err) } else if sleepSchedules != nil { set["sleepSchedules"] = sleepSchedules } @@ -158,7 +155,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { var datum *selfmonitored.SelfMonitored err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorDebug(datumID, err) + return errorHandler(datumID, err) } if *datum.Units != glucose.MgdL && *datum.Units != glucose.Mgdl { // NOTE: we need to ensure the same precision for the @@ -168,13 +165,13 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { } identityFields, err = datum.IdentityFields() if err != nil { - return errorDebug(datumID, err) + return errorHandler(datumID, err) } case ketone.Type: var datum *ketone.Ketone err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorDebug(datumID, err) + return errorHandler(datumID, err) } if *datum.Units != glucose.MgdL && *datum.Units != glucose.Mgdl { // NOTE: we need to ensure the same precision for the @@ -184,13 +181,13 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { } identityFields, err = datum.IdentityFields() if err != nil { - return errorDebug(datumID, err) + return errorHandler(datumID, err) } case continuous.Type: var datum *continuous.Continuous err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorDebug(datumID, err) + return errorHandler(datumID, err) } if *datum.Units != glucose.MgdL && *datum.Units != glucose.Mgdl { // NOTE: we need to ensure the same precision for the @@ -200,23 +197,23 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { } identityFields, err = datum.IdentityFields() if err != nil { - return errorDebug(datumID, err) + return errorHandler(datumID, err) } default: var datum *types.Base err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorDebug(datumID, err) + return errorHandler(datumID, err) } identityFields, err = datum.IdentityFields() if err != nil { - return errorDebug(datumID, err) + return errorHandler(datumID, err) } } hash, err := deduplicator.GenerateIdentityHash(identityFields) if err != nil { - return errorDebug(datumID, err) + return errorHandler(datumID, err) } set["_deduplicator"] = bson.M{"hash": hash} From f0714d7261c2fc84f8fc2acd68e81ffa70398c6c Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 20 Dec 2023 14:04:29 +1300 Subject: [PATCH 060/413] update user --- .../20231128_jellyfish_migration.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index dc3e8b8c19..573e97f9b8 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -364,8 +364,8 @@ func (m *Migration) fetchAndUpdateBatch() bool { selector := bson.M{ "_deduplicator": bson.M{"$exists": false}, - // testing based on _userId for jamie+qa3_1@tidepool.org - "_userId": "5e8cac61-6bef-4728-b490-c1d82087ed9c", + // testing based on _userId for jamie+qa3_2@tidepool.org + "_userId": "db0157c8-565e-4f67-92a5-dfb6b0f4c385", } // jellyfish uses a generated _id that is not an mongo objectId From 557ba9ec5a8d0184e6547f87ef01e4007e498342 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 20 Dec 2023 15:17:15 +1300 Subject: [PATCH 061/413] select all and update those without _deduplicator --- .../20231128_jellyfish_migration.go | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 573e97f9b8..26c0b4d24c 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -363,7 +363,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { start := time.Now() selector := bson.M{ - "_deduplicator": bson.M{"$exists": false}, + //"_deduplicator": bson.M{"$exists": false}, // testing based on _userId for jamie+qa3_2@tidepool.org "_userId": "db0157c8-565e-4f67-92a5-dfb6b0f4c385", } @@ -401,18 +401,19 @@ func (m *Migration) fetchAndUpdateBatch() bool { log.Printf("failed decoding data: %s", err) return false } - - datumID, datumUpdates, err := utils.GetDatumUpdates(dDataResult) - if err != nil { - m.onError(err, datumID, "failed getting updates") - continue + if dDataResult["_deduplicator"] == nil { + datumID, datumUpdates, err := utils.GetDatumUpdates(dDataResult) + if err != nil { + m.onError(err, datumID, "failed getting updates") + continue + } + + updateOp := mongo.NewUpdateOneModel() + updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": dDataResult["modifiedTime"]}) + updateOp.SetUpdate(datumUpdates) + m.updates = append(m.updates, updateOp) + m.lastUpdatedId = datumID } - - updateOp := mongo.NewUpdateOneModel() - updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": dDataResult["modifiedTime"]}) - updateOp.SetUpdate(datumUpdates) - m.updates = append(m.updates, updateOp) - m.lastUpdatedId = datumID } log.Printf("selector took %s", time.Since(start)) return len(m.updates) > 0 From 58238276acbab75e78d8e0e8dbfed522fd86514a Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 20 Dec 2023 15:35:20 +1300 Subject: [PATCH 062/413] _deduplicator clause to selector --- .../20231128_jellyfish_migration.go | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 26c0b4d24c..a2f504cf41 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -363,7 +363,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { start := time.Now() selector := bson.M{ - //"_deduplicator": bson.M{"$exists": false}, + "_deduplicator": bson.M{"$exists": false}, // testing based on _userId for jamie+qa3_2@tidepool.org "_userId": "db0157c8-565e-4f67-92a5-dfb6b0f4c385", } @@ -401,19 +401,17 @@ func (m *Migration) fetchAndUpdateBatch() bool { log.Printf("failed decoding data: %s", err) return false } - if dDataResult["_deduplicator"] == nil { - datumID, datumUpdates, err := utils.GetDatumUpdates(dDataResult) - if err != nil { - m.onError(err, datumID, "failed getting updates") - continue - } - - updateOp := mongo.NewUpdateOneModel() - updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": dDataResult["modifiedTime"]}) - updateOp.SetUpdate(datumUpdates) - m.updates = append(m.updates, updateOp) - m.lastUpdatedId = datumID + datumID, datumUpdates, err := utils.GetDatumUpdates(dDataResult) + if err != nil { + m.onError(err, datumID, "failed getting updates") + continue } + + updateOp := mongo.NewUpdateOneModel() + updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": dDataResult["modifiedTime"]}) + updateOp.SetUpdate(datumUpdates) + m.updates = append(m.updates, updateOp) + m.lastUpdatedId = datumID } log.Printf("selector took %s", time.Since(start)) return len(m.updates) > 0 From 7d34f3bff67d5fb31a1c1a2acd1031e83fd56bbc Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 20 Dec 2023 16:34:29 +1300 Subject: [PATCH 063/413] fix DurationMaximum for OverridePreset --- data/types/settings/pump/override_preset_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/data/types/settings/pump/override_preset_test.go b/data/types/settings/pump/override_preset_test.go index 4fee4045bb..e768a4e206 100644 --- a/data/types/settings/pump/override_preset_test.go +++ b/data/types/settings/pump/override_preset_test.go @@ -192,7 +192,7 @@ var _ = Describe("OverridePreset", func() { func(datum *dataTypesSettingsPump.OverridePreset, unitsBloodGlucose *string) { datum.Duration = pointer.FromInt(-1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-1, 0, 604800), "/duration"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-1, 0, dataTypesSettingsPump.DurationMaximum), "/duration"), ), Entry("duration; in range (lower)", pointer.FromString("mmol/L"), @@ -203,15 +203,15 @@ var _ = Describe("OverridePreset", func() { Entry("duration; in range (upper)", pointer.FromString("mmol/L"), func(datum *dataTypesSettingsPump.OverridePreset, unitsBloodGlucose *string) { - datum.Duration = pointer.FromInt(604800) + datum.Duration = pointer.FromInt(dataTypesSettingsPump.DurationMaximum) }, ), Entry("duration; out of range (upper)", pointer.FromString("mmol/L"), func(datum *dataTypesSettingsPump.OverridePreset, unitsBloodGlucose *string) { - datum.Duration = pointer.FromInt(604801) + datum.Duration = pointer.FromInt(604800001) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(604801, 0, 604800), "/duration"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(604800001, 0, dataTypesSettingsPump.DurationMaximum), "/duration"), ), Entry("units mmol/L; blood glucose target missing", pointer.FromString("mmol/L"), @@ -388,7 +388,7 @@ var _ = Describe("OverridePreset", func() { datum.InsulinSensitivityScaleFactor = pointer.FromFloat64(0.09) }, errorsTest.WithPointerSource(structureValidator.ErrorValueEmpty(), "/abbreviation"), - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-1, 0, 604800), "/duration"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-1, 0, dataTypesSettingsPump.DurationMaximum), "/duration"), errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(0.09, 0.1, 10.0), "/basalRateScaleFactor"), errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(0.09, 0.1, 10.0), "/carbRatioScaleFactor"), errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(0.09, 0.1, 10.0), "/insulinSensitivityScaleFactor"), From e992757327e443ad4f5a8f3bcb749b4d804ab60b Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 21 Dec 2023 08:31:31 +1300 Subject: [PATCH 064/413] timings --- .../20231128_jellyfish_migration.go | 12 ++++++++++-- .../20231128_jellyfish_migration/utils/utils.go | 1 - 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index a2f504cf41..e5d5b71764 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -360,7 +360,7 @@ func (m *Migration) blockUntilDBReady() error { } func (m *Migration) fetchAndUpdateBatch() bool { - start := time.Now() + fetchAndUpdateStart := time.Now() selector := bson.M{ "_deduplicator": bson.M{"$exists": false}, @@ -383,6 +383,9 @@ func (m *Migration) fetchAndUpdateBatch() bool { m.updates = []mongo.WriteModel{} if dataC := m.getDataCollection(); dataC != nil { + + fetchStart := time.Now() + dDataCursor, err := dataC.Find(m.ctx, selector, &options.FindOptions{ Limit: &m.config.readBatchSize, @@ -395,6 +398,9 @@ func (m *Migration) fetchAndUpdateBatch() bool { } defer dDataCursor.Close(m.ctx) + + log.Printf("fetch took %s", time.Since(fetchStart)) + updateStart := time.Now() for dDataCursor.Next(m.ctx) { var dDataResult bson.M if err = dDataCursor.Decode(&dDataResult); err != nil { @@ -413,7 +419,9 @@ func (m *Migration) fetchAndUpdateBatch() bool { m.updates = append(m.updates, updateOp) m.lastUpdatedId = datumID } - log.Printf("selector took %s", time.Since(start)) + + log.Printf("update took %s", time.Since(updateStart)) + log.Printf("fetch and update took %s", time.Since(fetchAndUpdateStart)) return len(m.updates) > 0 } return false diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 4af333e26c..7b2f9a60e4 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -221,6 +221,5 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { if rename != nil { updates["$rename"] = rename } - return datumID, updates, nil } From 24fbb04f49e17a43d13ee9bac15059c95ce1a29d Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 21 Dec 2023 08:38:32 +1300 Subject: [PATCH 065/413] new user --- .../20231128_jellyfish_migration.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index e5d5b71764..d1d1b096e2 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -365,7 +365,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { selector := bson.M{ "_deduplicator": bson.M{"$exists": false}, // testing based on _userId for jamie+qa3_2@tidepool.org - "_userId": "db0157c8-565e-4f67-92a5-dfb6b0f4c385", + "_userId": "e63e0997-5f92-4c8e-9707-0697f3339052", } // jellyfish uses a generated _id that is not an mongo objectId From 9b9d2d86a84c6c36ffb04bbf464fa86f2909d678 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 21 Dec 2023 09:58:16 +1300 Subject: [PATCH 066/413] debug of update timing --- .../utils/utils.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 7b2f9a60e4..e38f65b664 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -3,8 +3,10 @@ package utils import ( "encoding/json" "fmt" + "log" "slices" "strings" + "time" "go.mongodb.org/mongo-driver/bson" @@ -76,6 +78,7 @@ func GetBGValuePlatformPrecision(mmolVal float64) float64 { } func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { + start := time.Now() set := bson.M{} var rename bson.M var identityFields []string @@ -94,13 +97,17 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorHandler(datumID, errors.New("cannot get the datum type")) } + log.Printf("updates bsonData marshal start %s", time.Since(start)) dataBytes, err := bson.Marshal(bsonData) if err != nil { return errorHandler(datumID, err) } + log.Printf("updates bsonData marshal end %s", time.Since(start)) + switch datumType { case basal.Type: + log.Printf("updating basal start %s", time.Since(start)) var datum *basal.Basal err = bson.Unmarshal(dataBytes, &datum) if err != nil { @@ -111,6 +118,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorHandler(datumID, err) } case bolus.Type: + log.Printf("updating bolus start %s", time.Since(start)) var datum *bolus.Bolus err = bson.Unmarshal(dataBytes, &datum) if err != nil { @@ -121,6 +129,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorHandler(datumID, err) } case device.Type: + log.Printf("updating device event start %s", time.Since(start)) var datum *bolus.Bolus err = bson.Unmarshal(dataBytes, &datum) if err != nil { @@ -131,6 +140,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorHandler(datumID, err) } case pump.Type: + log.Printf("updating pump settings start %s", time.Since(start)) var datum *types.Base err = bson.Unmarshal(dataBytes, &datum) if err != nil { @@ -152,6 +162,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { set["sleepSchedules"] = sleepSchedules } case selfmonitored.Type: + log.Printf("updating smbg start %s", time.Since(start)) var datum *selfmonitored.SelfMonitored err = bson.Unmarshal(dataBytes, &datum) if err != nil { @@ -168,6 +179,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorHandler(datumID, err) } case ketone.Type: + log.Printf("updating ketone start %s", time.Since(start)) var datum *ketone.Ketone err = bson.Unmarshal(dataBytes, &datum) if err != nil { @@ -184,6 +196,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorHandler(datumID, err) } case continuous.Type: + log.Printf("updating cbg start %s", time.Since(start)) var datum *continuous.Continuous err = bson.Unmarshal(dataBytes, &datum) if err != nil { @@ -200,6 +213,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorHandler(datumID, err) } default: + log.Printf("updating generic start %s", time.Since(start)) var datum *types.Base err = bson.Unmarshal(dataBytes, &datum) if err != nil { @@ -211,10 +225,14 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { } } + log.Printf("updates made end %s", time.Since(start)) + log.Printf("generate hash start %s", time.Since(start)) hash, err := deduplicator.GenerateIdentityHash(identityFields) if err != nil { return errorHandler(datumID, err) } + + log.Printf("generate hash end %s", time.Since(start)) set["_deduplicator"] = bson.M{"hash": hash} var updates = bson.M{"$set": set} From 8bdd6db6c0b813e9c64fd2d7ebecbfd7d355b18f Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 21 Dec 2023 11:09:34 +1300 Subject: [PATCH 067/413] debug timings --- .../20231128_jellyfish_migration.go | 4 +-- .../utils/utils.go | 27 ++++++++++--------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index d1d1b096e2..a8bedfffc2 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -383,9 +383,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { m.updates = []mongo.WriteModel{} if dataC := m.getDataCollection(); dataC != nil { - fetchStart := time.Now() - dDataCursor, err := dataC.Find(m.ctx, selector, &options.FindOptions{ Limit: &m.config.readBatchSize, @@ -420,7 +418,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { m.lastUpdatedId = datumID } - log.Printf("update took %s", time.Since(updateStart)) + log.Printf("batch update took %s", time.Since(updateStart)) log.Printf("fetch and update took %s", time.Since(fetchAndUpdateStart)) return len(m.updates) > 0 } diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index e38f65b664..7f1f7d2562 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -97,17 +97,17 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorHandler(datumID, errors.New("cannot get the datum type")) } - log.Printf("updates bsonData marshal start %s", time.Since(start)) + //log.Printf("updates bsonData marshal start %s", time.Since(start)) dataBytes, err := bson.Marshal(bsonData) if err != nil { return errorHandler(datumID, err) } - log.Printf("updates bsonData marshal end %s", time.Since(start)) + //log.Printf("updates bsonData marshal end %s", time.Since(start)) switch datumType { case basal.Type: - log.Printf("updating basal start %s", time.Since(start)) + //log.Printf("updating basal start %s", time.Since(start)) var datum *basal.Basal err = bson.Unmarshal(dataBytes, &datum) if err != nil { @@ -118,7 +118,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorHandler(datumID, err) } case bolus.Type: - log.Printf("updating bolus start %s", time.Since(start)) + //log.Printf("updating bolus start %s", time.Since(start)) var datum *bolus.Bolus err = bson.Unmarshal(dataBytes, &datum) if err != nil { @@ -129,7 +129,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorHandler(datumID, err) } case device.Type: - log.Printf("updating device event start %s", time.Since(start)) + //log.Printf("updating device event start %s", time.Since(start)) var datum *bolus.Bolus err = bson.Unmarshal(dataBytes, &datum) if err != nil { @@ -140,7 +140,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorHandler(datumID, err) } case pump.Type: - log.Printf("updating pump settings start %s", time.Since(start)) + //log.Printf("updating pump settings start %s", time.Since(start)) var datum *types.Base err = bson.Unmarshal(dataBytes, &datum) if err != nil { @@ -162,7 +162,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { set["sleepSchedules"] = sleepSchedules } case selfmonitored.Type: - log.Printf("updating smbg start %s", time.Since(start)) + //log.Printf("updating smbg start %s", time.Since(start)) var datum *selfmonitored.SelfMonitored err = bson.Unmarshal(dataBytes, &datum) if err != nil { @@ -179,7 +179,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorHandler(datumID, err) } case ketone.Type: - log.Printf("updating ketone start %s", time.Since(start)) + //log.Printf("updating ketone start %s", time.Since(start)) var datum *ketone.Ketone err = bson.Unmarshal(dataBytes, &datum) if err != nil { @@ -196,7 +196,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorHandler(datumID, err) } case continuous.Type: - log.Printf("updating cbg start %s", time.Since(start)) + //log.Printf("updating cbg start %s", time.Since(start)) var datum *continuous.Continuous err = bson.Unmarshal(dataBytes, &datum) if err != nil { @@ -213,7 +213,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return errorHandler(datumID, err) } default: - log.Printf("updating generic start %s", time.Since(start)) + //log.Printf("updating generic start %s", time.Since(start)) var datum *types.Base err = bson.Unmarshal(dataBytes, &datum) if err != nil { @@ -225,19 +225,20 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { } } - log.Printf("updates made end %s", time.Since(start)) - log.Printf("generate hash start %s", time.Since(start)) + //log.Printf("updates made end %s", time.Since(start)) + //log.Printf("generate hash start %s", time.Since(start)) hash, err := deduplicator.GenerateIdentityHash(identityFields) if err != nil { return errorHandler(datumID, err) } - log.Printf("generate hash end %s", time.Since(start)) + //log.Printf("generate hash end %s", time.Since(start)) set["_deduplicator"] = bson.M{"hash": hash} var updates = bson.M{"$set": set} if rename != nil { updates["$rename"] = rename } + log.Printf("datum [%s] updates took %s", datumType, time.Since(start)) return datumID, updates, nil } From 72fcc8478789c0bcafa36ce0b8caafa1263e21ad Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 21 Dec 2023 12:16:14 +1300 Subject: [PATCH 068/413] timings --- .../20231128_jellyfish_migration.go | 9 ++++++++- migrations/20231128_jellyfish_migration/utils/utils.go | 5 ++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index a8bedfffc2..c77d5642c3 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -399,24 +399,31 @@ func (m *Migration) fetchAndUpdateBatch() bool { log.Printf("fetch took %s", time.Since(fetchStart)) updateStart := time.Now() + var totalDuration time.Duration for dDataCursor.Next(m.ctx) { + + start := time.Now() var dDataResult bson.M if err = dDataCursor.Decode(&dDataResult); err != nil { log.Printf("failed decoding data: %s", err) return false } + log.Printf("cursor decode %s", time.Since(start)) datumID, datumUpdates, err := utils.GetDatumUpdates(dDataResult) if err != nil { m.onError(err, datumID, "failed getting updates") continue } - + log.Printf("datum updates %s", time.Since(start)) updateOp := mongo.NewUpdateOneModel() updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": dDataResult["modifiedTime"]}) updateOp.SetUpdate(datumUpdates) m.updates = append(m.updates, updateOp) m.lastUpdatedId = datumID + log.Printf("added to updates %s", time.Since(start)) + totalDuration += time.Since(start) } + log.Printf("all datum %s", totalDuration) log.Printf("batch update took %s", time.Since(updateStart)) log.Printf("fetch and update took %s", time.Since(fetchAndUpdateStart)) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 7f1f7d2562..9dc99fc62d 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -239,6 +239,9 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { if rename != nil { updates["$rename"] = rename } - log.Printf("datum [%s] updates took %s", datumType, time.Since(start)) + duration := time.Since(start) + if duration > (time.Millisecond * 3) { + log.Printf("slow datum [%s] updates took %s", datumType, time.Since(start)) + } return datumID, updates, nil } From 00b3e7c50596607a307ed96ce43bbd4d8f1067f7 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 21 Dec 2023 13:23:21 +1300 Subject: [PATCH 069/413] cleanup and get time for select iteration --- .../20231128_jellyfish_migration.go | 50 +++++------ .../utils/utils.go | 86 ++++++++++++------- 2 files changed, 78 insertions(+), 58 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index c77d5642c3..88a71e55d4 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -14,8 +14,6 @@ import ( "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" - - "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" ) type Config struct { @@ -390,6 +388,8 @@ func (m *Migration) fetchAndUpdateBatch() bool { Sort: bson.M{"_id": 1}, }, ) + //dDataCursor.SetBatchSize(1000) + if err != nil { log.Printf("failed to select data: %s", err) return false @@ -399,33 +399,30 @@ func (m *Migration) fetchAndUpdateBatch() bool { log.Printf("fetch took %s", time.Since(fetchStart)) updateStart := time.Now() - var totalDuration time.Duration for dDataCursor.Next(m.ctx) { - start := time.Now() - var dDataResult bson.M - if err = dDataCursor.Decode(&dDataResult); err != nil { - log.Printf("failed decoding data: %s", err) - return false - } - log.Printf("cursor decode %s", time.Since(start)) - datumID, datumUpdates, err := utils.GetDatumUpdates(dDataResult) - if err != nil { - m.onError(err, datumID, "failed getting updates") - continue - } - log.Printf("datum updates %s", time.Since(start)) - updateOp := mongo.NewUpdateOneModel() - updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": dDataResult["modifiedTime"]}) - updateOp.SetUpdate(datumUpdates) - m.updates = append(m.updates, updateOp) - m.lastUpdatedId = datumID - log.Printf("added to updates %s", time.Since(start)) - totalDuration += time.Since(start) + // start := time.Now() + // var dDataResult bson.M + // if err = dDataCursor.Decode(&dDataResult); err != nil { + // log.Printf("failed decoding data: %s", err) + // return false + // } + // log.Printf("cursor decode %s", time.Since(start)) + // datumID, datumUpdates, err := utils.GetDatumUpdates(dDataResult) + // if err != nil { + // m.onError(err, datumID, "failed getting updates") + // continue + // } + // log.Printf("datum updates %s", time.Since(start)) + // updateOp := mongo.NewUpdateOneModel() + // updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": dDataResult["modifiedTime"]}) + // updateOp.SetUpdate(datumUpdates) + // m.updates = append(m.updates, updateOp) + // m.lastUpdatedId = datumID + // log.Printf("added to updates %s", time.Since(start)) } - log.Printf("all datum %s", totalDuration) - log.Printf("batch update took %s", time.Since(updateStart)) + log.Printf("batch iteration took %s", time.Since(updateStart)) log.Printf("fetch and update took %s", time.Since(fetchAndUpdateStart)) return len(m.updates) > 0 } @@ -433,6 +430,9 @@ func (m *Migration) fetchAndUpdateBatch() bool { } func (m *Migration) writeBatchUpdates() (int, error) { + if len(m.updates) == 0 { + return 0, nil + } start := time.Now() var getBatches = func(chunkSize int) [][]mongo.WriteModel { batches := [][]mongo.WriteModel{} diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 9dc99fc62d..371adce1fe 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -83,72 +83,76 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { var rename bson.M var identityFields []string - var errorHandler = func(id string, err error) (string, bson.M, error) { - return id, nil, err - } - datumID, ok := bsonData["_id"].(string) if !ok { - return errorHandler("", errors.New("cannot get the datum id")) + return "", nil, errors.New("cannot get the datum id") } datumType, ok := bsonData["type"].(string) if !ok { - return errorHandler(datumID, errors.New("cannot get the datum type")) - } - - //log.Printf("updates bsonData marshal start %s", time.Since(start)) - dataBytes, err := bson.Marshal(bsonData) - if err != nil { - return errorHandler(datumID, err) + return datumID, nil, errors.New("cannot get the datum type") } - //log.Printf("updates bsonData marshal end %s", time.Since(start)) - switch datumType { case basal.Type: //log.Printf("updating basal start %s", time.Since(start)) var datum *basal.Basal + dataBytes, err := bson.Marshal(bsonData) + if err != nil { + return datumID, nil, err + } err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorHandler(datumID, err) + return datumID, nil, err } identityFields, err = datum.IdentityFields() if err != nil { - return errorHandler(datumID, err) + return datumID, nil, err } case bolus.Type: //log.Printf("updating bolus start %s", time.Since(start)) var datum *bolus.Bolus + dataBytes, err := bson.Marshal(bsonData) + if err != nil { + return datumID, nil, err + } err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorHandler(datumID, err) + return datumID, nil, err } identityFields, err = datum.IdentityFields() if err != nil { - return errorHandler(datumID, err) + return datumID, nil, err } case device.Type: //log.Printf("updating device event start %s", time.Since(start)) var datum *bolus.Bolus + dataBytes, err := bson.Marshal(bsonData) + if err != nil { + return datumID, nil, err + } err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorHandler(datumID, err) + return datumID, nil, err } identityFields, err = datum.IdentityFields() if err != nil { - return errorHandler(datumID, err) + return datumID, nil, err } case pump.Type: //log.Printf("updating pump settings start %s", time.Since(start)) - var datum *types.Base + var datum types.Base + dataBytes, err := bson.Marshal(bsonData) + if err != nil { + return datumID, nil, err + } err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorHandler(datumID, err) + return datumID, nil, err } identityFields, err = datum.IdentityFields() if err != nil { - return errorHandler(datumID, err) + return datumID, nil, err } if pumpSettingsHasBolus(bsonData) { @@ -157,16 +161,20 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { sleepSchedules, err := updateIfExistsPumpSettingsSleepSchedules(bsonData) if err != nil { - return errorHandler(datumID, err) + return datumID, nil, err } else if sleepSchedules != nil { set["sleepSchedules"] = sleepSchedules } case selfmonitored.Type: //log.Printf("updating smbg start %s", time.Since(start)) var datum *selfmonitored.SelfMonitored + dataBytes, err := bson.Marshal(bsonData) + if err != nil { + return datumID, nil, err + } err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorHandler(datumID, err) + return datumID, nil, err } if *datum.Units != glucose.MgdL && *datum.Units != glucose.Mgdl { // NOTE: we need to ensure the same precision for the @@ -176,14 +184,18 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { } identityFields, err = datum.IdentityFields() if err != nil { - return errorHandler(datumID, err) + return datumID, nil, err } case ketone.Type: //log.Printf("updating ketone start %s", time.Since(start)) var datum *ketone.Ketone + dataBytes, err := bson.Marshal(bsonData) + if err != nil { + return datumID, nil, err + } err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorHandler(datumID, err) + return datumID, nil, err } if *datum.Units != glucose.MgdL && *datum.Units != glucose.Mgdl { // NOTE: we need to ensure the same precision for the @@ -193,14 +205,18 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { } identityFields, err = datum.IdentityFields() if err != nil { - return errorHandler(datumID, err) + return datumID, nil, err } case continuous.Type: //log.Printf("updating cbg start %s", time.Since(start)) var datum *continuous.Continuous + dataBytes, err := bson.Marshal(bsonData) + if err != nil { + return datumID, nil, err + } err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorHandler(datumID, err) + return datumID, nil, err } if *datum.Units != glucose.MgdL && *datum.Units != glucose.Mgdl { // NOTE: we need to ensure the same precision for the @@ -210,18 +226,22 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { } identityFields, err = datum.IdentityFields() if err != nil { - return errorHandler(datumID, err) + return datumID, nil, err } default: //log.Printf("updating generic start %s", time.Since(start)) var datum *types.Base + dataBytes, err := bson.Marshal(bsonData) + if err != nil { + return datumID, nil, err + } err = bson.Unmarshal(dataBytes, &datum) if err != nil { - return errorHandler(datumID, err) + return datumID, nil, err } identityFields, err = datum.IdentityFields() if err != nil { - return errorHandler(datumID, err) + return datumID, nil, err } } @@ -229,7 +249,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { //log.Printf("generate hash start %s", time.Since(start)) hash, err := deduplicator.GenerateIdentityHash(identityFields) if err != nil { - return errorHandler(datumID, err) + return datumID, nil, err } //log.Printf("generate hash end %s", time.Since(start)) From 02392b564d5def991e84cbe542a47f04e20c936a Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 21 Dec 2023 13:28:27 +1300 Subject: [PATCH 070/413] try dDataCursor.SetBatchSize(1000) --- .../20231128_jellyfish_migration.go | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 88a71e55d4..bf583a51c8 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -10,6 +10,7 @@ import ( "strings" "time" + "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" "github.com/urfave/cli" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" @@ -388,7 +389,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { Sort: bson.M{"_id": 1}, }, ) - //dDataCursor.SetBatchSize(1000) + dDataCursor.SetBatchSize(1000) if err != nil { log.Printf("failed to select data: %s", err) @@ -401,25 +402,25 @@ func (m *Migration) fetchAndUpdateBatch() bool { updateStart := time.Now() for dDataCursor.Next(m.ctx) { - // start := time.Now() - // var dDataResult bson.M - // if err = dDataCursor.Decode(&dDataResult); err != nil { - // log.Printf("failed decoding data: %s", err) - // return false - // } - // log.Printf("cursor decode %s", time.Since(start)) - // datumID, datumUpdates, err := utils.GetDatumUpdates(dDataResult) - // if err != nil { - // m.onError(err, datumID, "failed getting updates") - // continue - // } - // log.Printf("datum updates %s", time.Since(start)) - // updateOp := mongo.NewUpdateOneModel() - // updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": dDataResult["modifiedTime"]}) - // updateOp.SetUpdate(datumUpdates) - // m.updates = append(m.updates, updateOp) - // m.lastUpdatedId = datumID - // log.Printf("added to updates %s", time.Since(start)) + start := time.Now() + var dDataResult bson.M + if err = dDataCursor.Decode(&dDataResult); err != nil { + log.Printf("failed decoding data: %s", err) + return false + } + log.Printf("cursor decode %s", time.Since(start)) + datumID, datumUpdates, err := utils.GetDatumUpdates(dDataResult) + if err != nil { + m.onError(err, datumID, "failed getting updates") + continue + } + log.Printf("datum updates %s", time.Since(start)) + updateOp := mongo.NewUpdateOneModel() + updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": dDataResult["modifiedTime"]}) + updateOp.SetUpdate(datumUpdates) + m.updates = append(m.updates, updateOp) + m.lastUpdatedId = datumID + log.Printf("added to updates %s", time.Since(start)) } log.Printf("batch iteration took %s", time.Since(updateStart)) From 3f9d74f1f2ae23035d8e78234822c7d16b43e6ce Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 21 Dec 2023 13:35:19 +1300 Subject: [PATCH 071/413] less debug for clarity --- .../20231128_jellyfish_migration.go | 5 --- .../utils/utils.go | 32 ++++++------------- 2 files changed, 9 insertions(+), 28 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index bf583a51c8..b3b1eccad6 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -401,26 +401,21 @@ func (m *Migration) fetchAndUpdateBatch() bool { log.Printf("fetch took %s", time.Since(fetchStart)) updateStart := time.Now() for dDataCursor.Next(m.ctx) { - - start := time.Now() var dDataResult bson.M if err = dDataCursor.Decode(&dDataResult); err != nil { log.Printf("failed decoding data: %s", err) return false } - log.Printf("cursor decode %s", time.Since(start)) datumID, datumUpdates, err := utils.GetDatumUpdates(dDataResult) if err != nil { m.onError(err, datumID, "failed getting updates") continue } - log.Printf("datum updates %s", time.Since(start)) updateOp := mongo.NewUpdateOneModel() updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": dDataResult["modifiedTime"]}) updateOp.SetUpdate(datumUpdates) m.updates = append(m.updates, updateOp) m.lastUpdatedId = datumID - log.Printf("added to updates %s", time.Since(start)) } log.Printf("batch iteration took %s", time.Since(updateStart)) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 371adce1fe..a9cbdc492d 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -3,10 +3,8 @@ package utils import ( "encoding/json" "fmt" - "log" "slices" "strings" - "time" "go.mongodb.org/mongo-driver/bson" @@ -78,7 +76,6 @@ func GetBGValuePlatformPrecision(mmolVal float64) float64 { } func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { - start := time.Now() set := bson.M{} var rename bson.M var identityFields []string @@ -95,7 +92,6 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { switch datumType { case basal.Type: - //log.Printf("updating basal start %s", time.Since(start)) var datum *basal.Basal dataBytes, err := bson.Marshal(bsonData) if err != nil { @@ -110,7 +106,6 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return datumID, nil, err } case bolus.Type: - //log.Printf("updating bolus start %s", time.Since(start)) var datum *bolus.Bolus dataBytes, err := bson.Marshal(bsonData) if err != nil { @@ -125,8 +120,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return datumID, nil, err } case device.Type: - //log.Printf("updating device event start %s", time.Since(start)) - var datum *bolus.Bolus + var datum bolus.Bolus dataBytes, err := bson.Marshal(bsonData) if err != nil { return datumID, nil, err @@ -140,7 +134,6 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return datumID, nil, err } case pump.Type: - //log.Printf("updating pump settings start %s", time.Since(start)) var datum types.Base dataBytes, err := bson.Marshal(bsonData) if err != nil { @@ -166,8 +159,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { set["sleepSchedules"] = sleepSchedules } case selfmonitored.Type: - //log.Printf("updating smbg start %s", time.Since(start)) - var datum *selfmonitored.SelfMonitored + var datum selfmonitored.SelfMonitored dataBytes, err := bson.Marshal(bsonData) if err != nil { return datumID, nil, err @@ -187,8 +179,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return datumID, nil, err } case ketone.Type: - //log.Printf("updating ketone start %s", time.Since(start)) - var datum *ketone.Ketone + var datum ketone.Ketone dataBytes, err := bson.Marshal(bsonData) if err != nil { return datumID, nil, err @@ -208,8 +199,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return datumID, nil, err } case continuous.Type: - //log.Printf("updating cbg start %s", time.Since(start)) - var datum *continuous.Continuous + var datum continuous.Continuous dataBytes, err := bson.Marshal(bsonData) if err != nil { return datumID, nil, err @@ -229,8 +219,7 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { return datumID, nil, err } default: - //log.Printf("updating generic start %s", time.Since(start)) - var datum *types.Base + var datum types.Base dataBytes, err := bson.Marshal(bsonData) if err != nil { return datumID, nil, err @@ -245,23 +234,20 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { } } - //log.Printf("updates made end %s", time.Since(start)) - //log.Printf("generate hash start %s", time.Since(start)) hash, err := deduplicator.GenerateIdentityHash(identityFields) if err != nil { return datumID, nil, err } - //log.Printf("generate hash end %s", time.Since(start)) set["_deduplicator"] = bson.M{"hash": hash} var updates = bson.M{"$set": set} if rename != nil { updates["$rename"] = rename } - duration := time.Since(start) - if duration > (time.Millisecond * 3) { - log.Printf("slow datum [%s] updates took %s", datumType, time.Since(start)) - } + // duration := time.Since(start) + // if duration > (time.Millisecond * 3) { + // log.Printf("slow datum [%s] updates took %s", datumType, time.Since(start)) + // } return datumID, updates, nil } From 84e90b3baa1c99151366de861fdca5dfeca2cf32 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 21 Dec 2023 13:43:21 +1300 Subject: [PATCH 072/413] batch size as 1000 --- .../20231128_jellyfish_migration.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index b3b1eccad6..baed77ef70 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -381,15 +381,17 @@ func (m *Migration) fetchAndUpdateBatch() bool { m.updates = []mongo.WriteModel{} + size := int32(1000) + if dataC := m.getDataCollection(); dataC != nil { fetchStart := time.Now() dDataCursor, err := dataC.Find(m.ctx, selector, &options.FindOptions{ - Limit: &m.config.readBatchSize, - Sort: bson.M{"_id": 1}, + Limit: &m.config.readBatchSize, + Sort: bson.M{"_id": 1}, + BatchSize: &size, }, ) - dDataCursor.SetBatchSize(1000) if err != nil { log.Printf("failed to select data: %s", err) From 47d16a73d03caf415585a291e76c2a96ed735b16 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 21 Dec 2023 14:20:01 +1300 Subject: [PATCH 073/413] try to decode once via all --- .../20231128_jellyfish_migration.go | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index baed77ef70..e37813688c 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -385,9 +385,9 @@ func (m *Migration) fetchAndUpdateBatch() bool { if dataC := m.getDataCollection(); dataC != nil { fetchStart := time.Now() + dataSet := []bson.M{} dDataCursor, err := dataC.Find(m.ctx, selector, &options.FindOptions{ - Limit: &m.config.readBatchSize, Sort: bson.M{"_id": 1}, BatchSize: &size, }, @@ -398,27 +398,37 @@ func (m *Migration) fetchAndUpdateBatch() bool { return false } + err = dDataCursor.All(m.ctx, &dataSet) + + if err != nil { + log.Printf("decoding data: %s", err) + return false + } + defer dDataCursor.Close(m.ctx) - log.Printf("fetch took %s", time.Since(fetchStart)) + log.Printf("fetch took %s for %d items", time.Since(fetchStart), len(dataSet)) updateStart := time.Now() - for dDataCursor.Next(m.ctx) { - var dDataResult bson.M - if err = dDataCursor.Decode(&dDataResult); err != nil { - log.Printf("failed decoding data: %s", err) - return false - } - datumID, datumUpdates, err := utils.GetDatumUpdates(dDataResult) + for _, item := range dataSet { + + //for dDataCursor.Next(m.ctx) { + // var dDataResult bson.M + // if err = dDataCursor.Decode(&dDataResult); err != nil { + // log.Printf("failed decoding data: %s", err) + // return false + // } + datumID, datumUpdates, err := utils.GetDatumUpdates(item) if err != nil { m.onError(err, datumID, "failed getting updates") continue } updateOp := mongo.NewUpdateOneModel() - updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": dDataResult["modifiedTime"]}) + updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": item["modifiedTime"]}) updateOp.SetUpdate(datumUpdates) m.updates = append(m.updates, updateOp) m.lastUpdatedId = datumID } + //} log.Printf("batch iteration took %s", time.Since(updateStart)) log.Printf("fetch and update took %s", time.Since(fetchAndUpdateStart)) From a6fb33c93d641358b5c43e8e6833aa2b4aaca377 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 21 Dec 2023 14:35:29 +1300 Subject: [PATCH 074/413] with limit --- .../20231128_jellyfish_migration/20231128_jellyfish_migration.go | 1 + 1 file changed, 1 insertion(+) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index e37813688c..c711766229 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -388,6 +388,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { dataSet := []bson.M{} dDataCursor, err := dataC.Find(m.ctx, selector, &options.FindOptions{ + Limit: &m.config.readBatchSize, Sort: bson.M{"_id": 1}, BatchSize: &size, }, From 6220353b916a79ed591206bc74cccc1b25c6c97a Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 21 Dec 2023 14:42:27 +1300 Subject: [PATCH 075/413] new user --- .../20231128_jellyfish_migration.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index c711766229..bacc8140d3 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -364,7 +364,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { selector := bson.M{ "_deduplicator": bson.M{"$exists": false}, // testing based on _userId for jamie+qa3_2@tidepool.org - "_userId": "e63e0997-5f92-4c8e-9707-0697f3339052", + "_userId": "6d1ca155-68e6-4cd6-9ed2-1b8e743d5f4a", } // jellyfish uses a generated _id that is not an mongo objectId From d2979811b6dc587f74d307fb80ec6a57076af333 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 21 Dec 2023 14:45:52 +1300 Subject: [PATCH 076/413] no limit --- .../20231128_jellyfish_migration/20231128_jellyfish_migration.go | 1 - 1 file changed, 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index bacc8140d3..c3b50ec2a6 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -388,7 +388,6 @@ func (m *Migration) fetchAndUpdateBatch() bool { dataSet := []bson.M{} dDataCursor, err := dataC.Find(m.ctx, selector, &options.FindOptions{ - Limit: &m.config.readBatchSize, Sort: bson.M{"_id": 1}, BatchSize: &size, }, From a7cd7b60c8b28e597ab66477ed9233bf493c4e5f Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 21 Dec 2023 16:25:54 +1300 Subject: [PATCH 077/413] update durations --- .../override/settings/pump/pump_test.go | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/data/types/device/override/settings/pump/pump_test.go b/data/types/device/override/settings/pump/pump_test.go index 53dd8a20a6..ff3a05e97f 100644 --- a/data/types/device/override/settings/pump/pump_test.go +++ b/data/types/device/override/settings/pump/pump_test.go @@ -8,6 +8,7 @@ import ( dataBloodGlucoseTest "github.com/tidepool-org/platform/data/blood/glucose/test" dataNormalizer "github.com/tidepool-org/platform/data/normalizer" dataTypesDevice "github.com/tidepool-org/platform/data/types/device" + "github.com/tidepool-org/platform/data/types/device/override/settings/pump" dataTypesDeviceOverrideSettingsPump "github.com/tidepool-org/platform/data/types/device/override/settings/pump" dataTypesDeviceOverrideSettingsPumpTest "github.com/tidepool-org/platform/data/types/device/override/settings/pump/test" dataTypesTest "github.com/tidepool-org/platform/data/types/test" @@ -369,7 +370,7 @@ var _ = Describe("Pump", func() { datum.Duration = pointer.FromInt(-1) datum.DurationExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, pump.DurationMaximum), "/duration", NewMeta()), ), Entry("duration; in range (lower)", pointer.FromString("mmol/L"), @@ -388,15 +389,15 @@ var _ = Describe("Pump", func() { Entry("duration; out of range (upper)", pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { - datum.Duration = pointer.FromInt(604801) + datum.Duration = pointer.FromInt(pump.DurationMaximum + 1) datum.DurationExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604801, 0, 604800), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(pump.DurationMaximum+1, 0, pump.DurationMaximum), "/duration", NewMeta()), ), Entry("duration expected missing", pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { - datum.Duration = pointer.FromInt(test.RandomIntFromRange(0, 604800)) + datum.Duration = pointer.FromInt(test.RandomIntFromRange(0, pump.DurationMaximum)) datum.DurationExpected = nil }, ), @@ -406,7 +407,7 @@ var _ = Describe("Pump", func() { datum.Duration = nil datum.DurationExpected = pointer.FromInt(-1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, pump.DurationMaximum), "/expectedDuration", NewMeta()), ), Entry("duration expected; duration missing; in range (lower)", pointer.FromString("mmol/L"), @@ -419,16 +420,16 @@ var _ = Describe("Pump", func() { pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { datum.Duration = nil - datum.DurationExpected = pointer.FromInt(604800) + datum.DurationExpected = pointer.FromInt(pump.DurationMaximum) }, ), Entry("duration expected; duration missing; out of range (upper)", pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { datum.Duration = nil - datum.DurationExpected = pointer.FromInt(604801) + datum.DurationExpected = pointer.FromInt(pump.DurationMaximum + 1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604801, 0, 604800), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(pump.DurationMaximum+1, 0, pump.DurationMaximum), "/expectedDuration", NewMeta()), ), Entry("duration expected; duration out of range; out of range (lower)", pointer.FromString("mmol/L"), @@ -436,8 +437,8 @@ var _ = Describe("Pump", func() { datum.Duration = pointer.FromInt(-1) datum.DurationExpected = pointer.FromInt(-1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, pump.DurationMaximum), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, pump.DurationMaximum), "/expectedDuration", NewMeta()), ), Entry("duration expected; duration out of range; in range (lower)", pointer.FromString("mmol/L"), @@ -445,7 +446,7 @@ var _ = Describe("Pump", func() { datum.Duration = pointer.FromInt(-1) datum.DurationExpected = pointer.FromInt(0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, pump.DurationMaximum), "/duration", NewMeta()), ), Entry("duration expected; out of range (lower)", pointer.FromString("mmol/L"), @@ -453,7 +454,7 @@ var _ = Describe("Pump", func() { datum.Duration = pointer.FromInt(3600) datum.DurationExpected = pointer.FromInt(3599) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(3599, 3600, 604800), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(3599, 3600, pump.DurationMaximum), "/expectedDuration", NewMeta()), ), Entry("duration expected; in range (lower)", pointer.FromString("mmol/L"), @@ -473,9 +474,9 @@ var _ = Describe("Pump", func() { pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { datum.Duration = pointer.FromInt(3600) - datum.DurationExpected = pointer.FromInt(604801) + datum.DurationExpected = pointer.FromInt(pump.DurationMaximum + 1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604801, 3600, 604800), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(pump.DurationMaximum+1, 3600, pump.DurationMaximum), "/expectedDuration", NewMeta()), ), Entry("units mmol/L; blood glucose target missing", pointer.FromString("mmol/L"), @@ -707,8 +708,8 @@ var _ = Describe("Pump", func() { errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/overrideType", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueExists(), "/overridePreset", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"automatic", "manual"}), "/method", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800), "/duration", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800), "/expectedDuration", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, pump.DurationMaximum), "/duration", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, pump.DurationMaximum), "/expectedDuration", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(0.09, 0.1, 10.0), "/basalRateScaleFactor", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(0.09, 0.1, 10.0), "/carbRatioScaleFactor", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(0.09, 0.1, 10.0), "/insulinSensitivityScaleFactor", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), From b1466b4c50017b84bb7497076088270afa38b113 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 21 Dec 2023 16:37:11 +1300 Subject: [PATCH 078/413] import order --- .../20231128_jellyfish_migration.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index c3b50ec2a6..9483b69700 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -10,11 +10,12 @@ import ( "strings" "time" - "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" "github.com/urfave/cli" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" + + "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" ) type Config struct { From 97cfc0c6b3ef562f3204bf8360d5cae47949cc12 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 9 Jan 2024 09:53:13 +1300 Subject: [PATCH 079/413] timing for processing --- .../20231128_jellyfish_migration.go | 27 +++++++------------ 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 9483b69700..07a7e7aa71 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -205,18 +205,20 @@ func (m *Migration) prepare() error { } func (m *Migration) execute() error { - log.Printf("configured read batch size %d nop percent %d", m.config.readBatchSize, m.config.nopPercent) totalMigrated := 0 + migrateStart := time.Now() for m.fetchAndUpdateBatch() { + writeStart := time.Now() updatedCount, err := m.writeBatchUpdates() if err != nil { log.Printf("failed writing batch: %s", err) return err } + log.Printf("4. data write took [%s] for [%d] items", time.Since(writeStart), updatedCount) totalMigrated = totalMigrated + updatedCount - log.Printf("migrated %d for a total of %d migrated items", updatedCount, totalMigrated) } + log.Printf("migration took [%s] for [%d] items ", time.Since(migrateStart), totalMigrated) return nil } @@ -360,8 +362,6 @@ func (m *Migration) blockUntilDBReady() error { } func (m *Migration) fetchAndUpdateBatch() bool { - fetchAndUpdateStart := time.Now() - selector := bson.M{ "_deduplicator": bson.M{"$exists": false}, // testing based on _userId for jamie+qa3_2@tidepool.org @@ -393,12 +393,14 @@ func (m *Migration) fetchAndUpdateBatch() bool { BatchSize: &size, }, ) - if err != nil { log.Printf("failed to select data: %s", err) return false } + log.Printf("1. data fetch took [%s]", time.Since(fetchStart)) + + decodeStart := time.Now() err = dDataCursor.All(m.ctx, &dataSet) if err != nil { @@ -408,16 +410,9 @@ func (m *Migration) fetchAndUpdateBatch() bool { defer dDataCursor.Close(m.ctx) - log.Printf("fetch took %s for %d items", time.Since(fetchStart), len(dataSet)) + log.Printf("2. data decode took [%s] for [%d] items", time.Since(decodeStart), len(dataSet)) updateStart := time.Now() for _, item := range dataSet { - - //for dDataCursor.Next(m.ctx) { - // var dDataResult bson.M - // if err = dDataCursor.Decode(&dDataResult); err != nil { - // log.Printf("failed decoding data: %s", err) - // return false - // } datumID, datumUpdates, err := utils.GetDatumUpdates(item) if err != nil { m.onError(err, datumID, "failed getting updates") @@ -429,10 +424,8 @@ func (m *Migration) fetchAndUpdateBatch() bool { m.updates = append(m.updates, updateOp) m.lastUpdatedId = datumID } - //} - log.Printf("batch iteration took %s", time.Since(updateStart)) - log.Printf("fetch and update took %s", time.Since(fetchAndUpdateStart)) + log.Printf("3. data update took [%s] for [%d] items", time.Since(updateStart), len(m.updates)) return len(m.updates) > 0 } return false @@ -481,6 +474,6 @@ func (m *Migration) writeBatchUpdates() (int, error) { updateCount += int(results.ModifiedCount) } } - log.Printf("update took %s", time.Since(start)) + log.Printf("mongo bulk write took %s", time.Since(start)) return updateCount, nil } From 0fff52be459e05f89586ed86a3a666066b500961 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 9 Jan 2024 10:11:44 +1300 Subject: [PATCH 080/413] update to be able to test a single user --- .../20231128_jellyfish_migration.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 07a7e7aa71..3683c6aab4 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -43,6 +43,7 @@ type Migration struct { updates []mongo.WriteModel dryRun bool stopOnErr bool + migrateItemID string lastUpdatedId string } @@ -162,6 +163,12 @@ func (m *Migration) Initialize() error { //uri string comes from file called `uri` FilePath: "./uri", }, + cli.StringFlag{ + Name: "test-id", + Usage: "id of single user to migrate", + Destination: &m.migrateItemID, + Required: false, + }, ) return nil } @@ -364,8 +371,16 @@ func (m *Migration) blockUntilDBReady() error { func (m *Migration) fetchAndUpdateBatch() bool { selector := bson.M{ "_deduplicator": bson.M{"$exists": false}, - // testing based on _userId for jamie+qa3_2@tidepool.org - "_userId": "6d1ca155-68e6-4cd6-9ed2-1b8e743d5f4a", + } + + if m.migrateItemID != "" { + selector["_userId"] = m.migrateItemID + log.Printf("setting id of single user %v ", selector) + } + + if selector["_userId"] == nil { + log.Printf("testing so we need a user id %v", selector) + return false } // jellyfish uses a generated _id that is not an mongo objectId From aaf4a400a94d8d7c33a192ec1277c5cd3fce3a2c Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 9 Jan 2024 11:41:45 +1300 Subject: [PATCH 081/413] update order --- .../20231128_jellyfish_migration.go | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 3683c6aab4..c79ab33559 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -369,18 +369,14 @@ func (m *Migration) blockUntilDBReady() error { } func (m *Migration) fetchAndUpdateBatch() bool { - selector := bson.M{ - "_deduplicator": bson.M{"$exists": false}, - } - - if m.migrateItemID != "" { - selector["_userId"] = m.migrateItemID - log.Printf("setting id of single user %v ", selector) + if m.migrateItemID == "" { + log.Print("testing so we need a user id `--test-id=`") + return false } - if selector["_userId"] == nil { - log.Printf("testing so we need a user id %v", selector) - return false + selector := bson.M{ + "_deduplicator": bson.M{"$exists": false}, + "_userId": m.migrateItemID, } // jellyfish uses a generated _id that is not an mongo objectId @@ -397,6 +393,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { m.updates = []mongo.WriteModel{} + // TODO: balance with batch write size? size := int32(1000) if dataC := m.getDataCollection(); dataC != nil { @@ -408,11 +405,14 @@ func (m *Migration) fetchAndUpdateBatch() bool { BatchSize: &size, }, ) + if err != nil { log.Printf("failed to select data: %s", err) return false } + defer dDataCursor.Close(m.ctx) + log.Printf("1. data fetch took [%s]", time.Since(fetchStart)) decodeStart := time.Now() @@ -423,8 +423,6 @@ func (m *Migration) fetchAndUpdateBatch() bool { return false } - defer dDataCursor.Close(m.ctx) - log.Printf("2. data decode took [%s] for [%d] items", time.Since(decodeStart), len(dataSet)) updateStart := time.Now() for _, item := range dataSet { From 85131aedb8bd2b67ab8572472b2ea5325394fc4a Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 9 Jan 2024 16:28:19 +1300 Subject: [PATCH 082/413] allow both $set and $rename for one persist last update id to file --- .../20231128_jellyfish_migration.go | 45 +++++++++++++++---- .../utils/utils.go | 11 ++--- .../utils/utils_test.go | 31 ++++++++----- 3 files changed, 60 insertions(+), 27 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index c79ab33559..94ea6fc449 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -163,6 +163,14 @@ func (m *Migration) Initialize() error { //uri string comes from file called `uri` FilePath: "./uri", }, + cli.StringFlag{ + Name: "datum-id", + Usage: "id of last datum updated", + Destination: &m.lastUpdatedId, + Required: false, + //id of last datum updated read and written to file `lastUpdatedId` + FilePath: "./lastUpdatedId", + }, cli.StringFlag{ Name: "test-id", Usage: "id of single user to migrate", @@ -186,10 +194,6 @@ func (m *Migration) getOplogCollection() *mongo.Collection { func (m *Migration) onError(err error, id string, msg string) { var errFormat = "[id=%s] %s %s" if err != nil { - if m.stopOnErr { - log.Printf(errFormat, id, msg, err.Error()) - os.Exit(1) - } f, err := os.OpenFile("error.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { @@ -198,7 +202,25 @@ func (m *Migration) onError(err error, id string, msg string) { } defer f.Close() f.WriteString(fmt.Sprintf(errFormat, id, msg, err.Error())) + + writeLastItemUpdate(m.lastUpdatedId) + + if m.stopOnErr { + log.Printf(errFormat, id, msg, err.Error()) + os.Exit(1) + } + } +} + +func writeLastItemUpdate(itemID string) { + f, err := os.OpenFile("./lastUpdatedId", + os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Println(err) + os.Exit(1) } + defer f.Close() + f.WriteString(itemID) } func (m *Migration) prepare() error { @@ -260,6 +282,7 @@ func (m *Migration) getOplogDuration() (time.Duration, error) { } func (m *Migration) setWriteBatchSize() error { + // pass in config and mongo oplog collection var calculateBatchSize = func(oplogSize int, oplogEntryBytes int, oplogMinWindow int, nopPercent int) int64 { return int64(math.Floor(float64(oplogSize) / float64(oplogEntryBytes) / float64(oplogMinWindow) / (float64(nopPercent) / 7))) @@ -285,6 +308,8 @@ func (m *Migration) setWriteBatchSize() error { } func (m *Migration) checkFreeSpace() error { + // pass in config and mongo collection being migrated + type MongoMetaData struct { FsTotalSize int `json:"fsTotalSize"` FsUsedSize int `json:"fsUsedSize"` @@ -306,6 +331,7 @@ func (m *Migration) checkFreeSpace() error { } func (m *Migration) getWaitTime() (float64, error) { + // pass config and mongo admin db type Member struct { Name string `json:"name"` Health int `json:"health"` @@ -431,10 +457,12 @@ func (m *Migration) fetchAndUpdateBatch() bool { m.onError(err, datumID, "failed getting updates") continue } - updateOp := mongo.NewUpdateOneModel() - updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": item["modifiedTime"]}) - updateOp.SetUpdate(datumUpdates) - m.updates = append(m.updates, updateOp) + for _, update := range datumUpdates { + updateOp := mongo.NewUpdateOneModel() + updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": item["modifiedTime"]}) + updateOp.SetUpdate(update) + m.updates = append(m.updates, updateOp) + } m.lastUpdatedId = datumID } @@ -448,6 +476,7 @@ func (m *Migration) writeBatchUpdates() (int, error) { if len(m.updates) == 0 { return 0, nil } + writeLastItemUpdate(m.lastUpdatedId) start := time.Now() var getBatches = func(chunkSize int) [][]mongo.WriteModel { batches := [][]mongo.WriteModel{} diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index a9cbdc492d..d40d2ecc92 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -75,7 +75,8 @@ func GetBGValuePlatformPrecision(mmolVal float64) float64 { return mmolVal } -func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { +func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { + updates := []bson.M{} set := bson.M{} var rename bson.M var identityFields []string @@ -241,13 +242,9 @@ func GetDatumUpdates(bsonData bson.M) (string, bson.M, error) { set["_deduplicator"] = bson.M{"hash": hash} - var updates = bson.M{"$set": set} + updates = append(updates, bson.M{"$set": set}) if rename != nil { - updates["$rename"] = rename + updates = append(updates, bson.M{"$rename": rename}) } - // duration := time.Since(start) - // if duration > (time.Millisecond * 3) { - // log.Printf("slow datum [%s] updates took %s", datumType, time.Since(start)) - // } return datumID, updates, nil } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 012e30d1cc..f67385906e 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -57,7 +57,7 @@ var _ = Describe("back-37", func() { Context("_deduplicator hash", func() { DescribeTable("should", - func(getInput func() bson.M, expectedUpdates bson.M, expectError bool) { + func(getInput func() bson.M, expectedUpdates []bson.M, expectError bool) { input := getInput() actualID, actualUpdates, err := utils.GetDatumUpdates(input) if expectError { @@ -91,7 +91,12 @@ var _ = Describe("back-37", func() { }, nil, true), Entry("adds hash when vaild", func() bson.M { return existingBolusDatum - }, bson.M{"$set": bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}}, false), + }, + []bson.M{ + {"$set": bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}}, + }, + false, + ), ) }) @@ -123,7 +128,7 @@ var _ = Describe("back-37", func() { }) DescribeTable("should", - func(getInput func() bson.M, expected bson.M, expectError bool) { + func(getInput func() bson.M, expected []bson.M, expectError bool) { input := getInput() _, actual, err := utils.GetDatumUpdates(input) if expectError { @@ -143,7 +148,7 @@ var _ = Describe("back-37", func() { func() bson.M { return existingBolusDatum }, - bson.M{"$set": bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}}, + []bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}}}, false, ), Entry("do nothing when has no bolus", @@ -151,7 +156,7 @@ var _ = Describe("back-37", func() { settingsBolusDatum["bolus"] = nil return settingsBolusDatum }, - bson.M{"$set": bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}}, + []bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}}}, false, ), Entry("add boluses when bolus found", @@ -159,9 +164,9 @@ var _ = Describe("back-37", func() { settingsBolusDatum["bolus"] = bolusData return settingsBolusDatum }, - bson.M{ - "$set": bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}, - "$rename": bson.M{"bolus": "boluses"}, + []bson.M{ + {"$set": bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}}, + {"$rename": bson.M{"bolus": "boluses"}}, }, false, ), @@ -203,20 +208,22 @@ var _ = Describe("back-37", func() { It("does nothing when wrong type", func() { _, actual, err := utils.GetDatumUpdates(existingBolusDatum) Expect(err).To(BeNil()) - Expect(actual).To(Equal(bson.M{"$set": bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}})) + Expect(len(actual)).To(Equal(1)) + Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}}})) }) It("does nothing when no sleepSchedules", func() { sleepSchedulesDatum["sleepSchedules"] = nil _, actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) Expect(err).To(BeNil()) - Expect(actual).To(Equal(bson.M{"$set": bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}})) + Expect(len(actual)).To(Equal(1)) + Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}}})) }) It("returns updated sleepSchedules when valid", func() { sleepSchedulesDatum["sleepSchedules"] = []*pump.SleepSchedule{s1Days, s2Days} _, actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) Expect(err).To(BeNil()) - Expect(actual).ToNot(BeNil()) - setData := actual["$set"].(bson.M) + Expect(len(actual)).To(Equal(1)) + setData := actual[0]["$set"].(bson.M) Expect(setData["sleepSchedules"]).ToNot(BeNil()) Expect(setData["sleepSchedules"]).To(Equal(expectedSleepSchedulesMap)) }) From 6b08941e2dcebeda3513e4de3a33e61e7ce97532 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 9 Jan 2024 16:39:41 +1300 Subject: [PATCH 083/413] only set lastUpdatedId when not a dry run --- .../20231128_jellyfish_migration.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 94ea6fc449..1f4f3e4aff 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -203,7 +203,7 @@ func (m *Migration) onError(err error, id string, msg string) { defer f.Close() f.WriteString(fmt.Sprintf(errFormat, id, msg, err.Error())) - writeLastItemUpdate(m.lastUpdatedId) + writeLastItemUpdate(m.lastUpdatedId, m.dryRun) if m.stopOnErr { log.Printf(errFormat, id, msg, err.Error()) @@ -212,7 +212,11 @@ func (m *Migration) onError(err error, id string, msg string) { } } -func writeLastItemUpdate(itemID string) { +func writeLastItemUpdate(itemID string, dryRun bool) { + if dryRun { + log.Printf("dry run so not setting lastUpdatedId %s", itemID) + return + } f, err := os.OpenFile("./lastUpdatedId", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { @@ -476,7 +480,7 @@ func (m *Migration) writeBatchUpdates() (int, error) { if len(m.updates) == 0 { return 0, nil } - writeLastItemUpdate(m.lastUpdatedId) + writeLastItemUpdate(m.lastUpdatedId, m.dryRun) start := time.Now() var getBatches = func(chunkSize int) [][]mongo.WriteModel { batches := [][]mongo.WriteModel{} From 84cc5c537532b2ff973d22cb4e15ecf855922b99 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 10 Jan 2024 11:54:07 +1300 Subject: [PATCH 084/413] pull out common migration utility --- .../20231128_jellyfish_migration.go | 7 +- .../utils/migrationUtil.go | 324 ++++++++++++++++++ 2 files changed, 330 insertions(+), 1 deletion(-) create mode 100644 migrations/20231128_jellyfish_migration/utils/migrationUtil.go diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 1f4f3e4aff..110cafee94 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -463,7 +463,12 @@ func (m *Migration) fetchAndUpdateBatch() bool { } for _, update := range datumUpdates { updateOp := mongo.NewUpdateOneModel() - updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": item["modifiedTime"]}) + if update["$rename"] != nil { + log.Printf("rename op, 2 ops for same datum") + updateOp.SetFilter(bson.M{"_id": datumID}) + } else { + updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": item["modifiedTime"]}) + } updateOp.SetUpdate(update) m.updates = append(m.updates, updateOp) } diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go new file mode 100644 index 0000000000..ca38e20939 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -0,0 +1,324 @@ +package utils + +import ( + "context" + "errors" + "fmt" + "log" + "math" + "os" + "time" + + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + +type Config struct { + //apply no changes + dryRun bool + //halt on error + stopOnErr bool + minOplogWindow int + // these values are used to determine writes batches, first dividing the oplog's size with the desired duration and + // expected entry size, then adding a divisor to account for NOP overshoot in the oplog + expectedOplogEntrySize int + // how much of the oplog is NOP, this adjusts the batch to account for an oplog that is very change sensitive + // must be > 0 + // prod 0.6 + // idle 100 + nopPercent int + // minimum free disk space percent + minFreePercent int +} + +type migrationUtil struct { + writeBatchSize *int64 + client *mongo.Client + config *Config + updates []mongo.WriteModel + lastUpdatedId string +} + +const oplogName = "oplog.rs" + +// MigrationUtil helps managed the migration process +// errors written to +func NewMigrationUtil(client *mongo.Client, config *Config) (*migrationUtil, error) { + var err error + if client == nil { + err = errors.Join(err, errors.New("missing required mongo client")) + } + if config == nil { + err = errors.Join(err, errors.New("missing required configuration")) + } + + return &migrationUtil{ + client: client, + config: config, + updates: []mongo.WriteModel{}, + }, err +} + +func (m *migrationUtil) Initialize(ctx context.Context, dataC *mongo.Collection) error { + if err := m.checkFreeSpace(ctx, dataC); err != nil { + return err + } + if err := m.setWriteBatchSize(ctx); err != nil { + return err + } + return nil +} + +func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func(updates []mongo.WriteModel) bool) error { + totalMigrated := 0 + migrateStart := time.Now() + for fetchAndUpdateFn(m.updates) { + writeStart := time.Now() + updatedCount, err := m.writeUpdates(ctx, dataC) + if err != nil { + log.Printf("failed writing batch: %s", err) + return err + } + log.Printf("4. data write took [%s] for [%d] items", time.Since(writeStart), updatedCount) + totalMigrated = totalMigrated + updatedCount + } + log.Printf("migration took [%s] for [%d] items ", time.Since(migrateStart), totalMigrated) + return nil +} + +func (m *migrationUtil) getOplogCollection() *mongo.Collection { + return m.client.Database("local").Collection(oplogName) +} + +func (m *migrationUtil) getAdminDB() *mongo.Database { + return m.client.Database("admin") +} + +func (m *migrationUtil) onError(err error, id string, msg string) { + var errFormat = "[id=%s] %s %s" + if err != nil { + f, err := os.OpenFile("error.log", + os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Println(err) + os.Exit(1) + } + defer f.Close() + f.WriteString(fmt.Sprintf(errFormat, id, msg, err.Error())) + + writeLastItemUpdate(m.lastUpdatedId, m.config.dryRun) + + if m.config.stopOnErr { + log.Printf(errFormat, id, msg, err.Error()) + os.Exit(1) + } + } +} + +func writeLastItemUpdate(itemID string, dryRun bool) { + if dryRun { + log.Printf("dry run so not setting lastUpdatedId %s", itemID) + return + } + f, err := os.OpenFile("./lastUpdatedId", + os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Println(err) + os.Exit(1) + } + defer f.Close() + f.WriteString(itemID) +} + +func (m *migrationUtil) getOplogDuration(ctx context.Context) (time.Duration, error) { + type MongoMetaData struct { + Wall time.Time `json:"wall"` + } + if oplogC := m.getOplogCollection(); oplogC != nil { + var oldest MongoMetaData + if err := oplogC.FindOne( + ctx, + bson.M{"wall": bson.M{"$exists": true}}, + options.FindOne().SetSort(bson.M{"$natural": 1})).Decode(&oldest); err != nil { + return 0, err + } + + var newest MongoMetaData + if err := oplogC.FindOne( + ctx, + bson.M{"wall": bson.M{"$exists": true}}, + options.FindOne().SetSort(bson.M{"$natural": -1})).Decode(&newest); err != nil { + return 0, err + } + oplogDuration := newest.Wall.Sub(oldest.Wall) + log.Printf("current oplog duration: %v", oplogDuration) + return oplogDuration, nil + } + log.Println("Not clustered, not retrieving oplog duration.") + oplogDuration := time.Duration(m.config.minOplogWindow+1) * time.Second + return oplogDuration, nil + +} + +func (m *migrationUtil) setWriteBatchSize(ctx context.Context) error { + var calculateBatchSize = func(oplogSize int, oplogEntryBytes int, oplogMinWindow int, nopPercent int) int64 { + return int64(math.Floor(float64(oplogSize) / float64(oplogEntryBytes) / float64(oplogMinWindow) / (float64(nopPercent) / 7))) + } + + if oplogC := m.getOplogCollection(); oplogC != nil { + type MongoMetaData struct { + MaxSize int `json:"maxSize"` + } + var metaData MongoMetaData + if err := oplogC.Database().RunCommand(ctx, bson.M{"collStats": oplogName}).Decode(&metaData); err != nil { + return err + } + writeBatchSize := calculateBatchSize(metaData.MaxSize, m.config.expectedOplogEntrySize, m.config.minOplogWindow, m.config.nopPercent) + m.writeBatchSize = &writeBatchSize + log.Printf("calculated writeBatchSize: %d", writeBatchSize) + return nil + } + var writeBatchSize = int64(30000) + log.Printf("MongoDB is not clustered, removing write batch limit, setting to %d documents.", writeBatchSize) + m.writeBatchSize = &writeBatchSize + return nil +} + +func (m *migrationUtil) checkFreeSpace(ctx context.Context, dataC *mongo.Collection) error { + // pass in config and mongo collection being migrated + if dataC == nil { + return errors.New("missing required mongo data collection") + } + + type MongoMetaData struct { + FsTotalSize int `json:"fsTotalSize"` + FsUsedSize int `json:"fsUsedSize"` + } + var metaData MongoMetaData + if dataC != nil { + if err := dataC.Database().RunCommand(ctx, bson.M{"dbStats": 1}).Decode(&metaData); err != nil { + return err + } + bytesFree := metaData.FsTotalSize - metaData.FsUsedSize + percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) + log.Printf("DB disk currently has %d%% (%d bytes) free.", percentFree, bytesFree) + if m.config.minFreePercent > percentFree { + return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) + } + return nil + } + return errors.New("could not get deviceData database") +} + +func (m *migrationUtil) getWaitTime(ctx context.Context) (float64, error) { + type Member struct { + Name string `json:"name"` + Health int `json:"health"` + Uptime int `json:"uptime"` + State int `json:"state"` + } + + type MongoMetaData struct { + Members []Member `json:"members"` + } + + var metaData MongoMetaData + if err := m.getAdminDB().RunCommand(ctx, bson.M{"replSetGetStatus": 1}).Decode(&metaData); err != nil { + return 0, err + } + + for _, member := range metaData.Members { + if member.State < 1 || member.State > 2 || member.Health != 1 || member.Uptime < 120 { + log.Printf("DB member %s down or not ready.", member.Name) + return 240, nil + } + } + + oplogDuration, err := m.getOplogDuration(ctx) + if err != nil { + return 0, err + } + if oplogDuration.Seconds() < float64(m.config.minOplogWindow) { + minOplogWindowTime := time.Duration(m.config.minOplogWindow) * time.Second + log.Printf("DB oplog shorter than requested duration of %s, currently %s.", minOplogWindowTime, oplogDuration) + waitTime := float64(m.config.minOplogWindow) - oplogDuration.Seconds() + waitTime *= 1.15 + if waitTime < 600 { + waitTime = 600 + } + return waitTime, nil + } + return 0, nil +} + +func (m *migrationUtil) blockUntilDBReady(ctx context.Context) error { + waitTime, err := m.getWaitTime(ctx) + if err != nil { + return err + } + var totalWait float64 + for waitTime > 0 { + totalWait += waitTime + if totalWait > 1800 { + log.Printf("Long total wait of %s, possibly high load, or sustained DB outage. If neither, adjust NOP_PERCENT to reduce overshoot.", time.Duration(totalWait)*time.Second) + } + log.Printf("Sleeping for %d", time.Duration(waitTime)*time.Second) + time.Sleep(time.Duration(waitTime) * time.Second) + waitTime, err = m.getWaitTime(ctx) + if err != nil { + log.Printf("failed getting wait time %d", time.Duration(waitTime)*time.Second) + return err + } + } + return nil +} + +func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collection) (int, error) { + if dataC == nil { + return 0, errors.New("missing required collection to write updates to") + } + if len(m.updates) == 0 { + return 0, nil + } + + writeLastItemUpdate(m.lastUpdatedId, m.config.dryRun) + start := time.Now() + var getBatches = func(chunkSize int) [][]mongo.WriteModel { + batches := [][]mongo.WriteModel{} + for i := 0; i < len(m.updates); i += chunkSize { + end := i + chunkSize + if end > len(m.updates) { + end = len(m.updates) + } + batches = append(batches, m.updates[i:end]) + } + return batches + } + updateCount := 0 + for _, batch := range getBatches(int(*m.writeBatchSize)) { + if err := m.blockUntilDBReady(ctx); err != nil { + log.Printf("writeBatchUpdates-blocking error: %s", err) + return updateCount, err + } + if err := m.checkFreeSpace(ctx, dataC); err != nil { + log.Printf("writeBatchUpdates-freespace error: %s", err) + return updateCount, err + } + log.Printf("batch size to write %d", len(batch)) + + if m.config.dryRun { + updateCount += len(batch) + log.Println("dry run so not applying changes") + continue + } + results, err := dataC.BulkWrite(ctx, batch) + if err != nil { + log.Printf("error writing batch updates %v", err) + return updateCount, err + } + updateCount += int(results.ModifiedCount) + } + log.Printf("mongo bulk write took %s", time.Since(start)) + return updateCount, nil +} From 950c2c12c1a333694b00d70b97d4a04981efb352 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 10 Jan 2024 12:32:53 +1300 Subject: [PATCH 085/413] debug for dry run --- .../20231128_jellyfish_migration.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 110cafee94..70135a586c 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -421,6 +421,12 @@ func (m *Migration) fetchAndUpdateBatch() bool { selector["_id"] = idNotObjectID } + log.Printf("selector %v", selector) + if m.dryRun { + log.Println("bailing as a dry run") + return false + } + m.updates = []mongo.WriteModel{} // TODO: balance with batch write size? From 2e306d7838f9a8ecafd4aa861fc2263d3016ad3f Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 10 Jan 2024 12:42:48 +1300 Subject: [PATCH 086/413] fine tune options --- .../20231128_jellyfish_migration.go | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 70135a586c..f7c40eba7c 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -43,8 +43,8 @@ type Migration struct { updates []mongo.WriteModel dryRun bool stopOnErr bool - migrateItemID string - lastUpdatedId string + migrateItemID *string + lastUpdatedId *string } const oplogName = "oplog.rs" @@ -166,7 +166,7 @@ func (m *Migration) Initialize() error { cli.StringFlag{ Name: "datum-id", Usage: "id of last datum updated", - Destination: &m.lastUpdatedId, + Destination: m.lastUpdatedId, Required: false, //id of last datum updated read and written to file `lastUpdatedId` FilePath: "./lastUpdatedId", @@ -174,7 +174,7 @@ func (m *Migration) Initialize() error { cli.StringFlag{ Name: "test-id", Usage: "id of single user to migrate", - Destination: &m.migrateItemID, + Destination: m.migrateItemID, Required: false, }, ) @@ -212,9 +212,12 @@ func (m *Migration) onError(err error, id string, msg string) { } } -func writeLastItemUpdate(itemID string, dryRun bool) { +func writeLastItemUpdate(itemID *string, dryRun bool) { + if itemID == nil { + return + } if dryRun { - log.Printf("dry run so not setting lastUpdatedId %s", itemID) + log.Printf("dry run so not setting lastUpdatedId %s", *itemID) return } f, err := os.OpenFile("./lastUpdatedId", @@ -224,7 +227,7 @@ func writeLastItemUpdate(itemID string, dryRun bool) { os.Exit(1) } defer f.Close() - f.WriteString(itemID) + f.WriteString(*itemID) } func (m *Migration) prepare() error { @@ -399,22 +402,22 @@ func (m *Migration) blockUntilDBReady() error { } func (m *Migration) fetchAndUpdateBatch() bool { - if m.migrateItemID == "" { - log.Print("testing so we need a user id `--test-id=`") - return false - } selector := bson.M{ "_deduplicator": bson.M{"$exists": false}, - "_userId": m.migrateItemID, + } + + if m.migrateItemID != nil { + log.Print("focused test so we need a user id `--test-id=`") + selector["_userId"] = *m.migrateItemID } // jellyfish uses a generated _id that is not an mongo objectId idNotObjectID := bson.M{"$not": bson.M{"$type": "objectId"}} - if m.lastUpdatedId != "" { + if m.lastUpdatedId != nil { selector["$and"] = []interface{}{ - bson.M{"_id": bson.M{"$gt": m.lastUpdatedId}}, + bson.M{"_id": bson.M{"$gt": *m.lastUpdatedId}}, bson.M{"_id": idNotObjectID}, } } else { @@ -478,7 +481,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { updateOp.SetUpdate(update) m.updates = append(m.updates, updateOp) } - m.lastUpdatedId = datumID + m.lastUpdatedId = &datumID } log.Printf("3. data update took [%s] for [%d] items", time.Since(updateStart), len(m.updates)) From af6108623877fd1e2feb73a03a0ae8f987291857 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 10 Jan 2024 12:59:41 +1300 Subject: [PATCH 087/413] remove dry run block --- .../20231128_jellyfish_migration.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index f7c40eba7c..26a593b6b0 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -424,12 +424,6 @@ func (m *Migration) fetchAndUpdateBatch() bool { selector["_id"] = idNotObjectID } - log.Printf("selector %v", selector) - if m.dryRun { - log.Println("bailing as a dry run") - return false - } - m.updates = []mongo.WriteModel{} // TODO: balance with batch write size? From b856a3d1732ece879cffd1dd596bff96633e33a4 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 10 Jan 2024 13:35:24 +1300 Subject: [PATCH 088/413] defere close until after decode --- .../20231128_jellyfish_migration.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 26a593b6b0..e4a88721f5 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -444,17 +444,14 @@ func (m *Migration) fetchAndUpdateBatch() bool { return false } - defer dDataCursor.Close(m.ctx) - log.Printf("1. data fetch took [%s]", time.Since(fetchStart)) decodeStart := time.Now() - err = dDataCursor.All(m.ctx, &dataSet) - - if err != nil { - log.Printf("decoding data: %s", err) + if err := dDataCursor.All(m.ctx, &dataSet); err != nil { + log.Printf("error decoding data: %s", err) return false } + defer dDataCursor.Close(m.ctx) log.Printf("2. data decode took [%s] for [%d] items", time.Since(decodeStart), len(dataSet)) updateStart := time.Now() From 70fdac863995ff65b02f9f09a7021323f80e88b7 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 10 Jan 2024 14:19:04 +1300 Subject: [PATCH 089/413] move passed block --- .../20231128_jellyfish_migration.go | 4 ++-- migrations/20231128_jellyfish_migration/utils/utils.go | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index e4a88721f5..ff25d2f471 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -451,9 +451,9 @@ func (m *Migration) fetchAndUpdateBatch() bool { log.Printf("error decoding data: %s", err) return false } - defer dDataCursor.Close(m.ctx) - log.Printf("2. data decode took [%s] for [%d] items", time.Since(decodeStart), len(dataSet)) + //defer dDataCursor.Close(m.ctx) + updateStart := time.Now() for _, item := range dataSet { datumID, datumUpdates, err := utils.GetDatumUpdates(item) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index d40d2ecc92..6fc9162335 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -3,6 +3,7 @@ package utils import ( "encoding/json" "fmt" + "log" "slices" "strings" @@ -244,7 +245,11 @@ func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { updates = append(updates, bson.M{"$set": set}) if rename != nil { + log.Printf("rename %v", rename) updates = append(updates, bson.M{"$rename": rename}) } + if len(updates) != 1 { + log.Printf("datum updates %d", len(updates)) + } return datumID, updates, nil } From 7cd598a852a4be0e35c78336e46f9f2d5ade48b1 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 10 Jan 2024 14:27:05 +1300 Subject: [PATCH 090/413] defer close --- .../20231128_jellyfish_migration.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index ff25d2f471..cdf1f99640 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -444,7 +444,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { return false } - log.Printf("1. data fetch took [%s]", time.Since(fetchStart)) + log.Printf("1. data fetch [%v] took [%s]", selector, time.Since(fetchStart)) decodeStart := time.Now() if err := dDataCursor.All(m.ctx, &dataSet); err != nil { @@ -452,7 +452,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { return false } log.Printf("2. data decode took [%s] for [%d] items", time.Since(decodeStart), len(dataSet)) - //defer dDataCursor.Close(m.ctx) + defer dDataCursor.Close(m.ctx) updateStart := time.Now() for _, item := range dataSet { From ccbc1ea8d026c0dd927ba5cf4e0d73e4f92d276e Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 10 Jan 2024 15:01:34 +1300 Subject: [PATCH 091/413] use cursor iterator --- .../20231128_jellyfish_migration.go | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index cdf1f99640..423d2692a2 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -431,31 +431,41 @@ func (m *Migration) fetchAndUpdateBatch() bool { if dataC := m.getDataCollection(); dataC != nil { fetchStart := time.Now() - dataSet := []bson.M{} + dDataCursor, err := dataC.Find(m.ctx, selector, &options.FindOptions{ Sort: bson.M{"_id": 1}, BatchSize: &size, }, ) - if err != nil { log.Printf("failed to select data: %s", err) return false } + defer dDataCursor.Close(m.ctx) + log.Printf("1. data fetch [%v] took [%s]", selector, time.Since(fetchStart)) - decodeStart := time.Now() - if err := dDataCursor.All(m.ctx, &dataSet); err != nil { - log.Printf("error decoding data: %s", err) - return false - } - log.Printf("2. data decode took [%s] for [%d] items", time.Since(decodeStart), len(dataSet)) - defer dDataCursor.Close(m.ctx) + // decodeStart := time.Now() + // var dataSet []bson.M + // if err := dDataCursor.All(m.ctx, &dataSet); err != nil { + // log.Printf("error decoding data: %s", err) + // return false + // } + // log.Printf("2. data decode took [%s] for [%d] items", time.Since(decodeStart), len(dataSet)) updateStart := time.Now() - for _, item := range dataSet { + // for _, item := range dataSet { + + for dDataCursor.Next(m.ctx) { + + var item bson.M + if err := dDataCursor.Decode(&item); err != nil { + log.Printf("error decoding data: %s", err) + return false + } + datumID, datumUpdates, err := utils.GetDatumUpdates(item) if err != nil { m.onError(err, datumID, "failed getting updates") From 7f3e9d08cd332f93aeefa9b69f027f8655fe829e Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 10 Jan 2024 15:15:59 +1300 Subject: [PATCH 092/413] decode --- .../20231128_jellyfish_migration.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 423d2692a2..380e9a7ce7 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -192,8 +192,8 @@ func (m *Migration) getOplogCollection() *mongo.Collection { return m.client.Database("local").Collection(oplogName) } func (m *Migration) onError(err error, id string, msg string) { - var errFormat = "[id=%s] %s %s" if err != nil { + var errFormat = "[id=%s] %s %s" f, err := os.OpenFile("error.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { @@ -460,11 +460,12 @@ func (m *Migration) fetchAndUpdateBatch() bool { for dDataCursor.Next(m.ctx) { - var item bson.M + item := bson.M{} if err := dDataCursor.Decode(&item); err != nil { log.Printf("error decoding data: %s", err) return false } + log.Printf("got %v", item) datumID, datumUpdates, err := utils.GetDatumUpdates(item) if err != nil { From d755b08f3b53dfa2efdb1a2b3ec43b7b7fca745a Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 10 Jan 2024 15:43:41 +1300 Subject: [PATCH 093/413] fix err reporting require userID --- .../20231128_jellyfish_migration.go | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 380e9a7ce7..dd4cc56012 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -43,7 +43,7 @@ type Migration struct { updates []mongo.WriteModel dryRun bool stopOnErr bool - migrateItemID *string + userID *string lastUpdatedId *string } @@ -172,9 +172,9 @@ func (m *Migration) Initialize() error { FilePath: "./lastUpdatedId", }, cli.StringFlag{ - Name: "test-id", + Name: "user-id", Usage: "id of single user to migrate", - Destination: m.migrateItemID, + Destination: m.userID, Required: false, }, ) @@ -191,8 +191,8 @@ func (m *Migration) getDataCollection() *mongo.Collection { func (m *Migration) getOplogCollection() *mongo.Collection { return m.client.Database("local").Collection(oplogName) } -func (m *Migration) onError(err error, id string, msg string) { - if err != nil { +func (m *Migration) onError(errToReport error, id string, msg string) { + if errToReport != nil { var errFormat = "[id=%s] %s %s" f, err := os.OpenFile("error.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) @@ -201,12 +201,12 @@ func (m *Migration) onError(err error, id string, msg string) { os.Exit(1) } defer f.Close() - f.WriteString(fmt.Sprintf(errFormat, id, msg, err.Error())) + f.WriteString(fmt.Sprintf(errFormat, id, msg, errToReport.Error())) writeLastItemUpdate(m.lastUpdatedId, m.dryRun) if m.stopOnErr { - log.Printf(errFormat, id, msg, err.Error()) + log.Printf(errFormat, id, msg, errToReport.Error()) os.Exit(1) } } @@ -407,9 +407,12 @@ func (m *Migration) fetchAndUpdateBatch() bool { "_deduplicator": bson.M{"$exists": false}, } - if m.migrateItemID != nil { - log.Print("focused test so we need a user id `--test-id=`") - selector["_userId"] = *m.migrateItemID + if m.userID != nil { + log.Print("focused test so we need a user id `--user-id=`") + selector["_userId"] = *m.userID + } else { + log.Print("for testing we need a single user to migrate `--user-id=`") + return false } // jellyfish uses a generated _id that is not an mongo objectId From 73a61745e726fc567fe977507099492eefb9d1a0 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 10 Jan 2024 15:59:16 +1300 Subject: [PATCH 094/413] show args --- .../20231128_jellyfish_migration.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index dd4cc56012..1e18879b25 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -92,6 +92,8 @@ func (m *Migration) RunAndExit() { return nil } + log.Printf("args %v", os.Args) + if err := m.CLI().Run(os.Args); err != nil { if m.client != nil { m.client.Disconnect(m.ctx) @@ -188,9 +190,11 @@ func (m *Migration) CLI() *cli.App { func (m *Migration) getDataCollection() *mongo.Collection { return m.client.Database("data").Collection("deviceData") } + func (m *Migration) getOplogCollection() *mongo.Collection { return m.client.Database("local").Collection(oplogName) } + func (m *Migration) onError(errToReport error, id string, msg string) { if errToReport != nil { var errFormat = "[id=%s] %s %s" @@ -202,9 +206,7 @@ func (m *Migration) onError(errToReport error, id string, msg string) { } defer f.Close() f.WriteString(fmt.Sprintf(errFormat, id, msg, errToReport.Error())) - writeLastItemUpdate(m.lastUpdatedId, m.dryRun) - if m.stopOnErr { log.Printf(errFormat, id, msg, errToReport.Error()) os.Exit(1) @@ -245,7 +247,6 @@ func (m *Migration) execute() error { migrateStart := time.Now() for m.fetchAndUpdateBatch() { writeStart := time.Now() - updatedCount, err := m.writeBatchUpdates() if err != nil { log.Printf("failed writing batch: %s", err) From 16db0e7ae254fc8c016afeee663ed0f657db33ee Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 10 Jan 2024 16:17:59 +1300 Subject: [PATCH 095/413] userID as pointer not working --- .../20231128_jellyfish_migration.go | 35 +++++++------------ 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 1e18879b25..5c76e15bef 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -43,8 +43,8 @@ type Migration struct { updates []mongo.WriteModel dryRun bool stopOnErr bool - userID *string - lastUpdatedId *string + userID string + lastUpdatedId string } const oplogName = "oplog.rs" @@ -168,7 +168,7 @@ func (m *Migration) Initialize() error { cli.StringFlag{ Name: "datum-id", Usage: "id of last datum updated", - Destination: m.lastUpdatedId, + Destination: &m.lastUpdatedId, Required: false, //id of last datum updated read and written to file `lastUpdatedId` FilePath: "./lastUpdatedId", @@ -176,7 +176,7 @@ func (m *Migration) Initialize() error { cli.StringFlag{ Name: "user-id", Usage: "id of single user to migrate", - Destination: m.userID, + Destination: &m.userID, Required: false, }, ) @@ -214,12 +214,12 @@ func (m *Migration) onError(errToReport error, id string, msg string) { } } -func writeLastItemUpdate(itemID *string, dryRun bool) { - if itemID == nil { +func writeLastItemUpdate(itemID string, dryRun bool) { + if strings.TrimSpace(itemID) == "" { return } if dryRun { - log.Printf("dry run so not setting lastUpdatedId %s", *itemID) + log.Printf("dry run so not setting lastUpdatedId %s", itemID) return } f, err := os.OpenFile("./lastUpdatedId", @@ -229,7 +229,7 @@ func writeLastItemUpdate(itemID *string, dryRun bool) { os.Exit(1) } defer f.Close() - f.WriteString(*itemID) + f.WriteString(itemID) } func (m *Migration) prepare() error { @@ -408,9 +408,9 @@ func (m *Migration) fetchAndUpdateBatch() bool { "_deduplicator": bson.M{"$exists": false}, } - if m.userID != nil { + if strings.TrimSpace(m.userID) != "" { log.Print("focused test so we need a user id `--user-id=`") - selector["_userId"] = *m.userID + selector["_userId"] = m.userID } else { log.Print("for testing we need a single user to migrate `--user-id=`") return false @@ -419,9 +419,9 @@ func (m *Migration) fetchAndUpdateBatch() bool { // jellyfish uses a generated _id that is not an mongo objectId idNotObjectID := bson.M{"$not": bson.M{"$type": "objectId"}} - if m.lastUpdatedId != nil { + if strings.TrimSpace(m.lastUpdatedId) != "" { selector["$and"] = []interface{}{ - bson.M{"_id": bson.M{"$gt": *m.lastUpdatedId}}, + bson.M{"_id": bson.M{"$gt": m.lastUpdatedId}}, bson.M{"_id": idNotObjectID}, } } else { @@ -451,16 +451,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { log.Printf("1. data fetch [%v] took [%s]", selector, time.Since(fetchStart)) - // decodeStart := time.Now() - // var dataSet []bson.M - // if err := dDataCursor.All(m.ctx, &dataSet); err != nil { - // log.Printf("error decoding data: %s", err) - // return false - // } - // log.Printf("2. data decode took [%s] for [%d] items", time.Since(decodeStart), len(dataSet)) - updateStart := time.Now() - // for _, item := range dataSet { for dDataCursor.Next(m.ctx) { @@ -487,7 +478,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { updateOp.SetUpdate(update) m.updates = append(m.updates, updateOp) } - m.lastUpdatedId = &datumID + m.lastUpdatedId = datumID } log.Printf("3. data update took [%s] for [%d] items", time.Since(updateStart), len(m.updates)) From 054dfa9e1f5cc5405d3563d33de851af83e4def8 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 10 Jan 2024 16:26:07 +1300 Subject: [PATCH 096/413] update debug --- .../20231128_jellyfish_migration.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 5c76e15bef..ac61ddef78 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -252,7 +252,7 @@ func (m *Migration) execute() error { log.Printf("failed writing batch: %s", err) return err } - log.Printf("4. data write took [%s] for [%d] items", time.Since(writeStart), updatedCount) + log.Printf("3. data write took [%s] for [%d] items", time.Since(writeStart), updatedCount) totalMigrated = totalMigrated + updatedCount } log.Printf("migration took [%s] for [%d] items ", time.Since(migrateStart), totalMigrated) @@ -409,7 +409,6 @@ func (m *Migration) fetchAndUpdateBatch() bool { } if strings.TrimSpace(m.userID) != "" { - log.Print("focused test so we need a user id `--user-id=`") selector["_userId"] = m.userID } else { log.Print("for testing we need a single user to migrate `--user-id=`") @@ -481,7 +480,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { m.lastUpdatedId = datumID } - log.Printf("3. data update took [%s] for [%d] items", time.Since(updateStart), len(m.updates)) + log.Printf("2. data update took [%s] for [%d] items", time.Since(updateStart), len(m.updates)) return len(m.updates) > 0 } return false From 961c924265060bf57419f760be4d8370b7505ed6 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 10 Jan 2024 16:34:05 +1300 Subject: [PATCH 097/413] remove unwanted debug --- .../20231128_jellyfish_migration.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index ac61ddef78..8b308f84fa 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -280,7 +280,6 @@ func (m *Migration) getOplogDuration() (time.Duration, error) { return 0, err } oplogDuration := newest.Wall.Sub(oldest.Wall) - log.Printf("current oplog duration: %v", oplogDuration) return oplogDuration, nil } log.Println("Not clustered, not retrieving oplog duration.") @@ -329,7 +328,6 @@ func (m *Migration) checkFreeSpace() error { } bytesFree := metaData.FsTotalSize - metaData.FsUsedSize percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) - log.Printf("DB disk currently has %d%% (%d bytes) free.", percentFree, bytesFree) if m.config.minFreePercent > percentFree { return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) } @@ -459,7 +457,6 @@ func (m *Migration) fetchAndUpdateBatch() bool { log.Printf("error decoding data: %s", err) return false } - log.Printf("got %v", item) datumID, datumUpdates, err := utils.GetDatumUpdates(item) if err != nil { @@ -513,7 +510,6 @@ func (m *Migration) writeBatchUpdates() (int, error) { log.Printf("writeBatchUpdates-freespace error: %s", err) return updateCount, err } - log.Printf("batch size to write %d", len(batch)) if m.dryRun { updateCount += len(batch) From 2b69e82e63d25863646d839e738b3761800d81c9 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 10 Jan 2024 16:50:30 +1300 Subject: [PATCH 098/413] cleanup debugging --- .../20231128_jellyfish_migration.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 8b308f84fa..59a73424e1 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -252,10 +252,13 @@ func (m *Migration) execute() error { log.Printf("failed writing batch: %s", err) return err } - log.Printf("3. data write took [%s] for [%d] items", time.Since(writeStart), updatedCount) + log.Printf("3. write took [%s] for [%d] items", time.Since(writeStart), updatedCount) totalMigrated = totalMigrated + updatedCount } - log.Printf("migration took [%s] for [%d] items ", time.Since(migrateStart), totalMigrated) + log.Printf("migration completed in [%s] for [%d] items ", time.Since(migrateStart), totalMigrated) + if m.dryRun { + log.Println("no updates applied as run as a dry-run") + } return nil } @@ -513,7 +516,6 @@ func (m *Migration) writeBatchUpdates() (int, error) { if m.dryRun { updateCount += len(batch) - log.Println("dry run so not applying changes") continue } @@ -526,6 +528,8 @@ func (m *Migration) writeBatchUpdates() (int, error) { updateCount += int(results.ModifiedCount) } } - log.Printf("mongo bulk write took %s", time.Since(start)) + if !m.dryRun { + log.Printf("bulk write took %s", time.Since(start)) + } return updateCount, nil } From 7eb28059d4ff8aa244559a43aacd1fcbe32ba007 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 10 Jan 2024 17:03:34 +1300 Subject: [PATCH 099/413] allow for user or data cap for now --- .../20231128_jellyfish_migration.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 59a73424e1..6dd3fcf5bc 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -254,6 +254,10 @@ func (m *Migration) execute() error { } log.Printf("3. write took [%s] for [%d] items", time.Since(writeStart), updatedCount) totalMigrated = totalMigrated + updatedCount + if totalMigrated > 500000 { + log.Println("quitting after 500K records") + break + } } log.Printf("migration completed in [%s] for [%d] items ", time.Since(migrateStart), totalMigrated) if m.dryRun { @@ -410,10 +414,8 @@ func (m *Migration) fetchAndUpdateBatch() bool { } if strings.TrimSpace(m.userID) != "" { + log.Printf("fetching for user %s", m.userID) selector["_userId"] = m.userID - } else { - log.Print("for testing we need a single user to migrate `--user-id=`") - return false } // jellyfish uses a generated _id that is not an mongo objectId @@ -491,7 +493,6 @@ func (m *Migration) writeBatchUpdates() (int, error) { return 0, nil } writeLastItemUpdate(m.lastUpdatedId, m.dryRun) - start := time.Now() var getBatches = func(chunkSize int) [][]mongo.WriteModel { batches := [][]mongo.WriteModel{} for i := 0; i < len(m.updates); i += chunkSize { @@ -528,8 +529,5 @@ func (m *Migration) writeBatchUpdates() (int, error) { updateCount += int(results.ModifiedCount) } } - if !m.dryRun { - log.Printf("bulk write took %s", time.Since(start)) - } return updateCount, nil } From 6a66ffc2739c0e9f2b5a55e22ead1c9ab44e7104 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 10 Jan 2024 17:19:48 +1300 Subject: [PATCH 100/413] update to overwrite last id each time --- .../20231128_jellyfish_migration.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 6dd3fcf5bc..45daa0783d 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -197,7 +197,7 @@ func (m *Migration) getOplogCollection() *mongo.Collection { func (m *Migration) onError(errToReport error, id string, msg string) { if errToReport != nil { - var errFormat = "[id=%s] %s %s" + var errFormat = "[id=%s] %s %s\n" f, err := os.OpenFile("error.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { @@ -222,8 +222,7 @@ func writeLastItemUpdate(itemID string, dryRun bool) { log.Printf("dry run so not setting lastUpdatedId %s", itemID) return } - f, err := os.OpenFile("./lastUpdatedId", - os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + f, err := os.Create("./lastUpdatedId") if err != nil { log.Println(err) os.Exit(1) From e2643a5e0fc8914804c0e40ca1e6b2e6702def8c Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 11 Jan 2024 08:44:12 +1300 Subject: [PATCH 101/413] refine limit and batchsize --- .../20231128_jellyfish_migration.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 45daa0783d..319feb25e2 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -431,8 +431,10 @@ func (m *Migration) fetchAndUpdateBatch() bool { m.updates = []mongo.WriteModel{} - // TODO: balance with batch write size? - size := int32(1000) + // TODO: balance with batch write batchSize?? + + batchSize := int32(10000) + limit := int64(50000) if dataC := m.getDataCollection(); dataC != nil { fetchStart := time.Now() @@ -440,7 +442,8 @@ func (m *Migration) fetchAndUpdateBatch() bool { dDataCursor, err := dataC.Find(m.ctx, selector, &options.FindOptions{ Sort: bson.M{"_id": 1}, - BatchSize: &size, + BatchSize: &batchSize, + Limit: &limit, }, ) if err != nil { From 9112e29ad6ce735b3e67b23eab5a76739d887d39 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 11 Jan 2024 13:04:02 +1300 Subject: [PATCH 102/413] wip - split utils and fetch --- .../20231128_jellyfish_migration.go | 1066 ++++++++--------- .../jellyfish_migration.go | 255 ++++ .../utils/migrationUtil.go | 99 +- 3 files changed, 869 insertions(+), 551 deletions(-) create mode 100644 migrations/20231128_jellyfish_migration/jellyfish_migration.go diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go index 319feb25e2..44fb7e55e4 100644 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go @@ -1,535 +1,535 @@ package main -import ( - "context" - "errors" - "fmt" - "log" - "math" - "os" - "strings" - "time" - - "github.com/urfave/cli" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" - - "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" -) - -type Config struct { - uri string - minOplogWindow int - // these values are used to determine writes batches, first dividing the oplog's size with the desired duration and - // expected entry size, then adding a divisor to account for NOP overshoot in the oplog - expectedOplogEntrySize int - // how much of the oplog is NOP, this adjusts the batch to account for an oplog that is very change sensitive - // must be > 0 - // prod 0.6 - // idle 100 - nopPercent int - // minimum free disk space percent - minFreePercent int - readBatchSize int64 -} - -type Migration struct { - ctx context.Context - cli *cli.App - config *Config - client *mongo.Client - writeBatchSize *int64 - updates []mongo.WriteModel - dryRun bool - stopOnErr bool - userID string - lastUpdatedId string -} - -const oplogName = "oplog.rs" -const DryRunFlag = "dry-run" - -func main() { - ctx := context.Background() - ctx, cancel := context.WithCancel(ctx) - defer cancel() - migration := NewMigration(ctx) - migration.RunAndExit() - log.Println("finished migration") -} - -func NewMigration(ctx context.Context) *Migration { - return &Migration{ - ctx: ctx, - cli: cli.NewApp(), - config: &Config{}, - updates: []mongo.WriteModel{}, - stopOnErr: false, - } -} - -func (m *Migration) RunAndExit() { - if err := m.Initialize(); err != nil { - os.Exit(1) - } - - m.CLI().Action = func(ctx *cli.Context) error { - var err error - m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(strings.TrimSpace(m.config.uri))) - if err != nil { - return fmt.Errorf("unable to connect to MongoDB: %w", err) - } - defer m.client.Disconnect(m.ctx) - if err := m.prepare(); err != nil { - log.Printf("prepare failed: %s", err) - return err - } - if err := m.execute(); err != nil { - log.Printf("execute failed: %s", err) - return err - } - return nil - } - - log.Printf("args %v", os.Args) - - if err := m.CLI().Run(os.Args); err != nil { - if m.client != nil { - m.client.Disconnect(m.ctx) - } - os.Exit(1) - } -} - -func (m *Migration) Initialize() error { - m.CLI().Usage = "BACK-37: Migrate all existing data to add required Platform deduplication hash fields" - m.CLI().Description = "BACK-37: To fully migrate devices from the `jellyfish` upload API to the `platform` upload API" - m.CLI().Authors = []cli.Author{ - { - Name: "J H BATE", - Email: "jamie@tidepool.org", - }, - } - m.CLI().Flags = append(m.CLI().Flags, - cli.BoolFlag{ - Name: fmt.Sprintf("%s,%s", DryRunFlag, "n"), - Usage: "dry run only; do not migrate", - Destination: &m.dryRun, - }, - cli.BoolFlag{ - Name: "stop-error", - Usage: "stop migration on error", - Destination: &m.stopOnErr, - }, - cli.Int64Flag{ - Name: "batch-size", - Usage: "number of records to read each time", - Destination: &m.config.readBatchSize, - Value: 300, - Required: false, - }, - cli.IntFlag{ - Name: "min-free-percent", - Usage: "minimum free disk space percent", - Destination: &m.config.minFreePercent, - Value: 10, - Required: false, - }, - cli.IntFlag{ - Name: "nop-percent", - Usage: "how much of the oplog is NOP", - Destination: &m.config.nopPercent, - Value: 50, - Required: false, - }, - cli.IntFlag{ - Name: "oplog-entry-size", - Usage: "expected oplog entry size", - Destination: &m.config.expectedOplogEntrySize, - Value: 420, - Required: false, - }, - cli.IntFlag{ - Name: "oplog-window", - Usage: "minimum oplog window in seconds", - Destination: &m.config.minOplogWindow, - Value: 28800, // 8hrs - Required: false, - }, - cli.StringFlag{ - Name: "uri", - Usage: "mongo connection URI", - Destination: &m.config.uri, - Required: false, - //uri string comes from file called `uri` - FilePath: "./uri", - }, - cli.StringFlag{ - Name: "datum-id", - Usage: "id of last datum updated", - Destination: &m.lastUpdatedId, - Required: false, - //id of last datum updated read and written to file `lastUpdatedId` - FilePath: "./lastUpdatedId", - }, - cli.StringFlag{ - Name: "user-id", - Usage: "id of single user to migrate", - Destination: &m.userID, - Required: false, - }, - ) - return nil -} - -func (m *Migration) CLI() *cli.App { - return m.cli -} - -func (m *Migration) getDataCollection() *mongo.Collection { - return m.client.Database("data").Collection("deviceData") -} - -func (m *Migration) getOplogCollection() *mongo.Collection { - return m.client.Database("local").Collection(oplogName) -} - -func (m *Migration) onError(errToReport error, id string, msg string) { - if errToReport != nil { - var errFormat = "[id=%s] %s %s\n" - f, err := os.OpenFile("error.log", - os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - log.Println(err) - os.Exit(1) - } - defer f.Close() - f.WriteString(fmt.Sprintf(errFormat, id, msg, errToReport.Error())) - writeLastItemUpdate(m.lastUpdatedId, m.dryRun) - if m.stopOnErr { - log.Printf(errFormat, id, msg, errToReport.Error()) - os.Exit(1) - } - } -} - -func writeLastItemUpdate(itemID string, dryRun bool) { - if strings.TrimSpace(itemID) == "" { - return - } - if dryRun { - log.Printf("dry run so not setting lastUpdatedId %s", itemID) - return - } - f, err := os.Create("./lastUpdatedId") - if err != nil { - log.Println(err) - os.Exit(1) - } - defer f.Close() - f.WriteString(itemID) -} - -func (m *Migration) prepare() error { - if err := m.checkFreeSpace(); err != nil { - return err - } - if err := m.setWriteBatchSize(); err != nil { - return err - } - return nil -} - -func (m *Migration) execute() error { - totalMigrated := 0 - migrateStart := time.Now() - for m.fetchAndUpdateBatch() { - writeStart := time.Now() - updatedCount, err := m.writeBatchUpdates() - if err != nil { - log.Printf("failed writing batch: %s", err) - return err - } - log.Printf("3. write took [%s] for [%d] items", time.Since(writeStart), updatedCount) - totalMigrated = totalMigrated + updatedCount - if totalMigrated > 500000 { - log.Println("quitting after 500K records") - break - } - } - log.Printf("migration completed in [%s] for [%d] items ", time.Since(migrateStart), totalMigrated) - if m.dryRun { - log.Println("no updates applied as run as a dry-run") - } - return nil -} - -func (m *Migration) getOplogDuration() (time.Duration, error) { - type MongoMetaData struct { - Wall time.Time `json:"wall"` - } - if oplogC := m.getOplogCollection(); oplogC != nil { - var oldest MongoMetaData - if err := oplogC.FindOne( - m.ctx, - bson.M{"wall": bson.M{"$exists": true}}, - options.FindOne().SetSort(bson.M{"$natural": 1})).Decode(&oldest); err != nil { - return 0, err - } - - var newest MongoMetaData - if err := oplogC.FindOne( - m.ctx, - bson.M{"wall": bson.M{"$exists": true}}, - options.FindOne().SetSort(bson.M{"$natural": -1})).Decode(&newest); err != nil { - return 0, err - } - oplogDuration := newest.Wall.Sub(oldest.Wall) - return oplogDuration, nil - } - log.Println("Not clustered, not retrieving oplog duration.") - oplogDuration := time.Duration(m.config.minOplogWindow+1) * time.Second - return oplogDuration, nil - -} - -func (m *Migration) setWriteBatchSize() error { - // pass in config and mongo oplog collection - - var calculateBatchSize = func(oplogSize int, oplogEntryBytes int, oplogMinWindow int, nopPercent int) int64 { - return int64(math.Floor(float64(oplogSize) / float64(oplogEntryBytes) / float64(oplogMinWindow) / (float64(nopPercent) / 7))) - } - - if oplogC := m.getOplogCollection(); oplogC != nil { - type MongoMetaData struct { - MaxSize int `json:"maxSize"` - } - var metaData MongoMetaData - if err := oplogC.Database().RunCommand(m.ctx, bson.M{"collStats": oplogName}).Decode(&metaData); err != nil { - return err - } - writeBatchSize := calculateBatchSize(metaData.MaxSize, m.config.expectedOplogEntrySize, m.config.minOplogWindow, m.config.nopPercent) - m.writeBatchSize = &writeBatchSize - log.Printf("calculated writeBatchSize: %d", writeBatchSize) - return nil - } - var writeBatchSize = int64(30000) - log.Printf("MongoDB is not clustered, removing write batch limit, setting to %d documents.", writeBatchSize) - m.writeBatchSize = &writeBatchSize - return nil -} - -func (m *Migration) checkFreeSpace() error { - // pass in config and mongo collection being migrated - - type MongoMetaData struct { - FsTotalSize int `json:"fsTotalSize"` - FsUsedSize int `json:"fsUsedSize"` - } - var metaData MongoMetaData - if dataC := m.getDataCollection(); dataC != nil { - if err := dataC.Database().RunCommand(m.ctx, bson.M{"dbStats": 1}).Decode(&metaData); err != nil { - return err - } - bytesFree := metaData.FsTotalSize - metaData.FsUsedSize - percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) - if m.config.minFreePercent > percentFree { - return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) - } - return nil - } - return errors.New("could not get deviceData database") -} - -func (m *Migration) getWaitTime() (float64, error) { - // pass config and mongo admin db - type Member struct { - Name string `json:"name"` - Health int `json:"health"` - Uptime int `json:"uptime"` - State int `json:"state"` - } - - type MongoMetaData struct { - Members []Member `json:"members"` - } - - var metaData MongoMetaData - if err := m.client.Database("admin").RunCommand(m.ctx, bson.M{"replSetGetStatus": 1}).Decode(&metaData); err != nil { - return 0, err - } - - for _, member := range metaData.Members { - if member.State < 1 || member.State > 2 || member.Health != 1 || member.Uptime < 120 { - log.Printf("DB member %s down or not ready.", member.Name) - return 240, nil - } - } - - oplogDuration, err := m.getOplogDuration() - if err != nil { - return 0, err - } - if oplogDuration.Seconds() < float64(m.config.minOplogWindow) { - minOplogWindowTime := time.Duration(m.config.minOplogWindow) * time.Second - log.Printf("DB oplog shorter than requested duration of %s, currently %s.", minOplogWindowTime, oplogDuration) - waitTime := float64(m.config.minOplogWindow) - oplogDuration.Seconds() - waitTime *= 1.15 - if waitTime < 600 { - waitTime = 600 - } - return waitTime, nil - } - return 0, nil -} - -func (m *Migration) blockUntilDBReady() error { - waitTime, err := m.getWaitTime() - if err != nil { - return err - } - var totalWait float64 - for waitTime > 0 { - totalWait += waitTime - if totalWait > 1800 { - log.Printf("Long total wait of %s, possibly high load, or sustained DB outage. If neither, adjust NOP_PERCENT to reduce overshoot.", time.Duration(totalWait)*time.Second) - } - log.Printf("Sleeping for %d", time.Duration(waitTime)*time.Second) - time.Sleep(time.Duration(waitTime) * time.Second) - waitTime, err = m.getWaitTime() - if err != nil { - log.Printf("failed getting wait time %d", time.Duration(waitTime)*time.Second) - return err - } - } - return nil -} - -func (m *Migration) fetchAndUpdateBatch() bool { - - selector := bson.M{ - "_deduplicator": bson.M{"$exists": false}, - } - - if strings.TrimSpace(m.userID) != "" { - log.Printf("fetching for user %s", m.userID) - selector["_userId"] = m.userID - } - - // jellyfish uses a generated _id that is not an mongo objectId - idNotObjectID := bson.M{"$not": bson.M{"$type": "objectId"}} - - if strings.TrimSpace(m.lastUpdatedId) != "" { - selector["$and"] = []interface{}{ - bson.M{"_id": bson.M{"$gt": m.lastUpdatedId}}, - bson.M{"_id": idNotObjectID}, - } - } else { - selector["_id"] = idNotObjectID - } - - m.updates = []mongo.WriteModel{} - - // TODO: balance with batch write batchSize?? - - batchSize := int32(10000) - limit := int64(50000) - - if dataC := m.getDataCollection(); dataC != nil { - fetchStart := time.Now() - - dDataCursor, err := dataC.Find(m.ctx, selector, - &options.FindOptions{ - Sort: bson.M{"_id": 1}, - BatchSize: &batchSize, - Limit: &limit, - }, - ) - if err != nil { - log.Printf("failed to select data: %s", err) - return false - } - - defer dDataCursor.Close(m.ctx) - - log.Printf("1. data fetch [%v] took [%s]", selector, time.Since(fetchStart)) - - updateStart := time.Now() - - for dDataCursor.Next(m.ctx) { - - item := bson.M{} - if err := dDataCursor.Decode(&item); err != nil { - log.Printf("error decoding data: %s", err) - return false - } - - datumID, datumUpdates, err := utils.GetDatumUpdates(item) - if err != nil { - m.onError(err, datumID, "failed getting updates") - continue - } - for _, update := range datumUpdates { - updateOp := mongo.NewUpdateOneModel() - if update["$rename"] != nil { - log.Printf("rename op, 2 ops for same datum") - updateOp.SetFilter(bson.M{"_id": datumID}) - } else { - updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": item["modifiedTime"]}) - } - updateOp.SetUpdate(update) - m.updates = append(m.updates, updateOp) - } - m.lastUpdatedId = datumID - } - - log.Printf("2. data update took [%s] for [%d] items", time.Since(updateStart), len(m.updates)) - return len(m.updates) > 0 - } - return false -} - -func (m *Migration) writeBatchUpdates() (int, error) { - if len(m.updates) == 0 { - return 0, nil - } - writeLastItemUpdate(m.lastUpdatedId, m.dryRun) - var getBatches = func(chunkSize int) [][]mongo.WriteModel { - batches := [][]mongo.WriteModel{} - for i := 0; i < len(m.updates); i += chunkSize { - end := i + chunkSize - if end > len(m.updates) { - end = len(m.updates) - } - batches = append(batches, m.updates[i:end]) - } - return batches - } - updateCount := 0 - for _, batch := range getBatches(int(*m.writeBatchSize)) { - if err := m.blockUntilDBReady(); err != nil { - log.Printf("writeBatchUpdates-blocking error: %s", err) - return updateCount, err - } - if err := m.checkFreeSpace(); err != nil { - log.Printf("writeBatchUpdates-freespace error: %s", err) - return updateCount, err - } - - if m.dryRun { - updateCount += len(batch) - continue - } - - if deviceC := m.getDataCollection(); deviceC != nil { - results, err := deviceC.BulkWrite(m.ctx, batch) - if err != nil { - log.Printf("error writing batch updates %v", err) - return updateCount, err - } - updateCount += int(results.ModifiedCount) - } - } - return updateCount, nil -} +// import ( +// "context" +// "errors" +// "fmt" +// "log" +// "math" +// "os" +// "strings" +// "time" + +// "github.com/urfave/cli" +// "go.mongodb.org/mongo-driver/bson" +// "go.mongodb.org/mongo-driver/mongo" +// "go.mongodb.org/mongo-driver/mongo/options" + +// "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" +// ) + +// type Config struct { +// uri string +// minOplogWindow int +// // these values are used to determine writes batches, first dividing the oplog's size with the desired duration and +// // expected entry size, then adding a divisor to account for NOP overshoot in the oplog +// expectedOplogEntrySize int +// // how much of the oplog is NOP, this adjusts the batch to account for an oplog that is very change sensitive +// // must be > 0 +// // prod 0.6 +// // idle 100 +// nopPercent int +// // minimum free disk space percent +// minFreePercent int +// readBatchSize int64 +// } + +// type Migration struct { +// ctx context.Context +// cli *cli.App +// config *Config +// client *mongo.Client +// writeBatchSize *int64 +// updates []mongo.WriteModel +// dryRun bool +// stopOnErr bool +// userID string +// lastUpdatedId string +// } + +// const oplogName = "oplog.rs" +// const DryRunFlag = "dry-run" + +// func main() { +// ctx := context.Background() +// ctx, cancel := context.WithCancel(ctx) +// defer cancel() +// migration := NewMigration(ctx) +// migration.RunAndExit() +// log.Println("finished migration") +// } + +// func NewMigration(ctx context.Context) *Migration { +// return &Migration{ +// ctx: ctx, +// cli: cli.NewApp(), +// config: &Config{}, +// updates: []mongo.WriteModel{}, +// stopOnErr: false, +// } +// } + +// func (m *Migration) RunAndExit() { +// if err := m.Initialize(); err != nil { +// os.Exit(1) +// } + +// m.CLI().Action = func(ctx *cli.Context) error { +// var err error +// m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(strings.TrimSpace(m.config.uri))) +// if err != nil { +// return fmt.Errorf("unable to connect to MongoDB: %w", err) +// } +// defer m.client.Disconnect(m.ctx) +// if err := m.prepare(); err != nil { +// log.Printf("prepare failed: %s", err) +// return err +// } +// if err := m.execute(); err != nil { +// log.Printf("execute failed: %s", err) +// return err +// } +// return nil +// } + +// log.Printf("args %v", os.Args) + +// if err := m.CLI().Run(os.Args); err != nil { +// if m.client != nil { +// m.client.Disconnect(m.ctx) +// } +// os.Exit(1) +// } +// } + +// func (m *Migration) Initialize() error { +// m.CLI().Usage = "BACK-37: Migrate all existing data to add required Platform deduplication hash fields" +// m.CLI().Description = "BACK-37: To fully migrate devices from the `jellyfish` upload API to the `platform` upload API" +// m.CLI().Authors = []cli.Author{ +// { +// Name: "J H BATE", +// Email: "jamie@tidepool.org", +// }, +// } +// m.CLI().Flags = append(m.CLI().Flags, +// cli.BoolFlag{ +// Name: fmt.Sprintf("%s,%s", DryRunFlag, "n"), +// Usage: "dry run only; do not migrate", +// Destination: &m.dryRun, +// }, +// cli.BoolFlag{ +// Name: "stop-error", +// Usage: "stop migration on error", +// Destination: &m.stopOnErr, +// }, +// cli.Int64Flag{ +// Name: "batch-size", +// Usage: "number of records to read each time", +// Destination: &m.config.readBatchSize, +// Value: 300, +// Required: false, +// }, +// cli.IntFlag{ +// Name: "min-free-percent", +// Usage: "minimum free disk space percent", +// Destination: &m.config.minFreePercent, +// Value: 10, +// Required: false, +// }, +// cli.IntFlag{ +// Name: "nop-percent", +// Usage: "how much of the oplog is NOP", +// Destination: &m.config.nopPercent, +// Value: 50, +// Required: false, +// }, +// cli.IntFlag{ +// Name: "oplog-entry-size", +// Usage: "expected oplog entry size", +// Destination: &m.config.expectedOplogEntrySize, +// Value: 420, +// Required: false, +// }, +// cli.IntFlag{ +// Name: "oplog-window", +// Usage: "minimum oplog window in seconds", +// Destination: &m.config.minOplogWindow, +// Value: 28800, // 8hrs +// Required: false, +// }, +// cli.StringFlag{ +// Name: "uri", +// Usage: "mongo connection URI", +// Destination: &m.config.uri, +// Required: false, +// //uri string comes from file called `uri` +// FilePath: "./uri", +// }, +// cli.StringFlag{ +// Name: "datum-id", +// Usage: "id of last datum updated", +// Destination: &m.lastUpdatedId, +// Required: false, +// //id of last datum updated read and written to file `lastUpdatedId` +// FilePath: "./lastUpdatedId", +// }, +// cli.StringFlag{ +// Name: "user-id", +// Usage: "id of single user to migrate", +// Destination: &m.userID, +// Required: false, +// }, +// ) +// return nil +// } + +// func (m *Migration) CLI() *cli.App { +// return m.cli +// } + +// func (m *Migration) getDataCollection() *mongo.Collection { +// return m.client.Database("data").Collection("deviceData") +// } + +// func (m *Migration) getOplogCollection() *mongo.Collection { +// return m.client.Database("local").Collection(oplogName) +// } + +// func (m *Migration) onError(errToReport error, id string, msg string) { +// if errToReport != nil { +// var errFormat = "[id=%s] %s %s\n" +// f, err := os.OpenFile("error.log", +// os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) +// if err != nil { +// log.Println(err) +// os.Exit(1) +// } +// defer f.Close() +// f.WriteString(fmt.Sprintf(errFormat, id, msg, errToReport.Error())) +// writeLastItemUpdate(m.lastUpdatedId, m.dryRun) +// if m.stopOnErr { +// log.Printf(errFormat, id, msg, errToReport.Error()) +// os.Exit(1) +// } +// } +// } + +// func writeLastItemUpdate(itemID string, dryRun bool) { +// if strings.TrimSpace(itemID) == "" { +// return +// } +// if dryRun { +// log.Printf("dry run so not setting lastUpdatedId %s", itemID) +// return +// } +// f, err := os.Create("./lastUpdatedId") +// if err != nil { +// log.Println(err) +// os.Exit(1) +// } +// defer f.Close() +// f.WriteString(itemID) +// } + +// func (m *Migration) prepare() error { +// if err := m.checkFreeSpace(); err != nil { +// return err +// } +// if err := m.setWriteBatchSize(); err != nil { +// return err +// } +// return nil +// } + +// func (m *Migration) execute() error { +// totalMigrated := 0 +// migrateStart := time.Now() +// for m.fetchAndUpdateBatch() { +// writeStart := time.Now() +// updatedCount, err := m.writeBatchUpdates() +// if err != nil { +// log.Printf("failed writing batch: %s", err) +// return err +// } +// log.Printf("3. write took [%s] for [%d] items", time.Since(writeStart), updatedCount) +// totalMigrated = totalMigrated + updatedCount +// if totalMigrated > 500000 { +// log.Println("quitting after 500K records") +// break +// } +// } +// log.Printf("migration completed in [%s] for [%d] items ", time.Since(migrateStart), totalMigrated) +// if m.dryRun { +// log.Println("no updates applied as run as a dry-run") +// } +// return nil +// } + +// func (m *Migration) getOplogDuration() (time.Duration, error) { +// type MongoMetaData struct { +// Wall time.Time `json:"wall"` +// } +// if oplogC := m.getOplogCollection(); oplogC != nil { +// var oldest MongoMetaData +// if err := oplogC.FindOne( +// m.ctx, +// bson.M{"wall": bson.M{"$exists": true}}, +// options.FindOne().SetSort(bson.M{"$natural": 1})).Decode(&oldest); err != nil { +// return 0, err +// } + +// var newest MongoMetaData +// if err := oplogC.FindOne( +// m.ctx, +// bson.M{"wall": bson.M{"$exists": true}}, +// options.FindOne().SetSort(bson.M{"$natural": -1})).Decode(&newest); err != nil { +// return 0, err +// } +// oplogDuration := newest.Wall.Sub(oldest.Wall) +// return oplogDuration, nil +// } +// log.Println("Not clustered, not retrieving oplog duration.") +// oplogDuration := time.Duration(m.config.minOplogWindow+1) * time.Second +// return oplogDuration, nil + +// } + +// func (m *Migration) setWriteBatchSize() error { +// // pass in config and mongo oplog collection + +// var calculateBatchSize = func(oplogSize int, oplogEntryBytes int, oplogMinWindow int, nopPercent int) int64 { +// return int64(math.Floor(float64(oplogSize) / float64(oplogEntryBytes) / float64(oplogMinWindow) / (float64(nopPercent) / 7))) +// } + +// if oplogC := m.getOplogCollection(); oplogC != nil { +// type MongoMetaData struct { +// MaxSize int `json:"maxSize"` +// } +// var metaData MongoMetaData +// if err := oplogC.Database().RunCommand(m.ctx, bson.M{"collStats": oplogName}).Decode(&metaData); err != nil { +// return err +// } +// writeBatchSize := calculateBatchSize(metaData.MaxSize, m.config.expectedOplogEntrySize, m.config.minOplogWindow, m.config.nopPercent) +// m.writeBatchSize = &writeBatchSize +// log.Printf("calculated writeBatchSize: %d", writeBatchSize) +// return nil +// } +// var writeBatchSize = int64(30000) +// log.Printf("MongoDB is not clustered, removing write batch limit, setting to %d documents.", writeBatchSize) +// m.writeBatchSize = &writeBatchSize +// return nil +// } + +// func (m *Migration) checkFreeSpace() error { +// // pass in config and mongo collection being migrated + +// type MongoMetaData struct { +// FsTotalSize int `json:"fsTotalSize"` +// FsUsedSize int `json:"fsUsedSize"` +// } +// var metaData MongoMetaData +// if dataC := m.getDataCollection(); dataC != nil { +// if err := dataC.Database().RunCommand(m.ctx, bson.M{"dbStats": 1}).Decode(&metaData); err != nil { +// return err +// } +// bytesFree := metaData.FsTotalSize - metaData.FsUsedSize +// percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) +// if m.config.minFreePercent > percentFree { +// return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) +// } +// return nil +// } +// return errors.New("could not get deviceData database") +// } + +// func (m *Migration) getWaitTime() (float64, error) { +// // pass config and mongo admin db +// type Member struct { +// Name string `json:"name"` +// Health int `json:"health"` +// Uptime int `json:"uptime"` +// State int `json:"state"` +// } + +// type MongoMetaData struct { +// Members []Member `json:"members"` +// } + +// var metaData MongoMetaData +// if err := m.client.Database("admin").RunCommand(m.ctx, bson.M{"replSetGetStatus": 1}).Decode(&metaData); err != nil { +// return 0, err +// } + +// for _, member := range metaData.Members { +// if member.State < 1 || member.State > 2 || member.Health != 1 || member.Uptime < 120 { +// log.Printf("DB member %s down or not ready.", member.Name) +// return 240, nil +// } +// } + +// oplogDuration, err := m.getOplogDuration() +// if err != nil { +// return 0, err +// } +// if oplogDuration.Seconds() < float64(m.config.minOplogWindow) { +// minOplogWindowTime := time.Duration(m.config.minOplogWindow) * time.Second +// log.Printf("DB oplog shorter than requested duration of %s, currently %s.", minOplogWindowTime, oplogDuration) +// waitTime := float64(m.config.minOplogWindow) - oplogDuration.Seconds() +// waitTime *= 1.15 +// if waitTime < 600 { +// waitTime = 600 +// } +// return waitTime, nil +// } +// return 0, nil +// } + +// func (m *Migration) blockUntilDBReady() error { +// waitTime, err := m.getWaitTime() +// if err != nil { +// return err +// } +// var totalWait float64 +// for waitTime > 0 { +// totalWait += waitTime +// if totalWait > 1800 { +// log.Printf("Long total wait of %s, possibly high load, or sustained DB outage. If neither, adjust NOP_PERCENT to reduce overshoot.", time.Duration(totalWait)*time.Second) +// } +// log.Printf("Sleeping for %d", time.Duration(waitTime)*time.Second) +// time.Sleep(time.Duration(waitTime) * time.Second) +// waitTime, err = m.getWaitTime() +// if err != nil { +// log.Printf("failed getting wait time %d", time.Duration(waitTime)*time.Second) +// return err +// } +// } +// return nil +// } + +// func (m *Migration) fetchAndUpdateBatch() bool { + +// selector := bson.M{ +// "_deduplicator": bson.M{"$exists": false}, +// } + +// if strings.TrimSpace(m.userID) != "" { +// log.Printf("fetching for user %s", m.userID) +// selector["_userId"] = m.userID +// } + +// // jellyfish uses a generated _id that is not an mongo objectId +// idNotObjectID := bson.M{"$not": bson.M{"$type": "objectId"}} + +// if strings.TrimSpace(m.lastUpdatedId) != "" { +// selector["$and"] = []interface{}{ +// bson.M{"_id": bson.M{"$gt": m.lastUpdatedId}}, +// bson.M{"_id": idNotObjectID}, +// } +// } else { +// selector["_id"] = idNotObjectID +// } + +// m.updates = []mongo.WriteModel{} + +// // TODO: balance with batch write batchSize?? + +// batchSize := int32(10000) +// limit := int64(50000) + +// if dataC := m.getDataCollection(); dataC != nil { +// fetchStart := time.Now() + +// dDataCursor, err := dataC.Find(m.ctx, selector, +// &options.FindOptions{ +// Sort: bson.M{"_id": 1}, +// BatchSize: &batchSize, +// Limit: &limit, +// }, +// ) +// if err != nil { +// log.Printf("failed to select data: %s", err) +// return false +// } + +// defer dDataCursor.Close(m.ctx) + +// log.Printf("1. data fetch [%v] took [%s]", selector, time.Since(fetchStart)) + +// updateStart := time.Now() + +// for dDataCursor.Next(m.ctx) { + +// item := bson.M{} +// if err := dDataCursor.Decode(&item); err != nil { +// log.Printf("error decoding data: %s", err) +// return false +// } + +// datumID, datumUpdates, err := utils.GetDatumUpdates(item) +// if err != nil { +// m.onError(err, datumID, "failed getting updates") +// continue +// } +// for _, update := range datumUpdates { +// updateOp := mongo.NewUpdateOneModel() +// if update["$rename"] != nil { +// log.Printf("rename op, 2 ops for same datum") +// updateOp.SetFilter(bson.M{"_id": datumID}) +// } else { +// updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": item["modifiedTime"]}) +// } +// updateOp.SetUpdate(update) +// m.updates = append(m.updates, updateOp) +// } +// m.lastUpdatedId = datumID +// } + +// log.Printf("2. data update took [%s] for [%d] items", time.Since(updateStart), len(m.updates)) +// return len(m.updates) > 0 +// } +// return false +// } + +// func (m *Migration) writeBatchUpdates() (int, error) { +// if len(m.updates) == 0 { +// return 0, nil +// } +// writeLastItemUpdate(m.lastUpdatedId, m.dryRun) +// var getBatches = func(chunkSize int) [][]mongo.WriteModel { +// batches := [][]mongo.WriteModel{} +// for i := 0; i < len(m.updates); i += chunkSize { +// end := i + chunkSize +// if end > len(m.updates) { +// end = len(m.updates) +// } +// batches = append(batches, m.updates[i:end]) +// } +// return batches +// } +// updateCount := 0 +// for _, batch := range getBatches(int(*m.writeBatchSize)) { +// if err := m.blockUntilDBReady(); err != nil { +// log.Printf("writeBatchUpdates-blocking error: %s", err) +// return updateCount, err +// } +// if err := m.checkFreeSpace(); err != nil { +// log.Printf("writeBatchUpdates-freespace error: %s", err) +// return updateCount, err +// } + +// if m.dryRun { +// updateCount += len(batch) +// continue +// } + +// if deviceC := m.getDataCollection(); deviceC != nil { +// results, err := deviceC.BulkWrite(m.ctx, batch) +// if err != nil { +// log.Printf("error writing batch updates %v", err) +// return updateCount, err +// } +// updateCount += int(results.ModifiedCount) +// } +// } +// return updateCount, nil +// } diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go new file mode 100644 index 0000000000..03c67b5011 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -0,0 +1,255 @@ +package main + +import ( + "context" + "fmt" + "log" + "os" + "strings" + "time" + + "github.com/urfave/cli" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + + "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" +) + +type Migration struct { + ctx context.Context + cli *cli.App + config *config + client *mongo.Client + migrationUtil utils.MigrationUtil +} + +type config struct { + uri string + dryRun bool + stopOnErr bool + userID string + lastUpdatedId string + minFreePercent int + nopPercent int + readBatchSize int64 +} + +const DryRunFlag = "dry-run" + +func main() { + ctx := context.Background() + ctx, cancel := context.WithCancel(ctx) + defer cancel() + migration := NewMigration(ctx) + migration.RunAndExit() + log.Println("finished migration") +} + +func NewMigration(ctx context.Context) *Migration { + return &Migration{ + config: &config{}, + ctx: ctx, + cli: cli.NewApp(), + } +} + +func (m *Migration) RunAndExit() { + if err := m.Initialize(); err != nil { + os.Exit(1) + } + + m.CLI().Action = func(ctx *cli.Context) error { + + var err error + m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(strings.TrimSpace(m.config.uri))) + if err != nil { + return fmt.Errorf("unable to connect to MongoDB: %w", err) + } + defer m.client.Disconnect(m.ctx) + + m.migrationUtil, err = utils.NewMigrationUtil( + utils.NewMigrationUtilConfig(&m.config.dryRun, &m.config.stopOnErr, &m.config.nopPercent), + m.client, + ) + if err != nil { + return fmt.Errorf("unable init migration utils : %w", err) + } + + if err := m.migrationUtil.Initialize(m.ctx, m.getDataCollection()); err != nil { + log.Printf("prepare failed: %s", err) + return err + } + if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndUpdateBatch); err != nil { + log.Printf("execute failed: %s", err) + return err + } + return nil + } + + if err := m.CLI().Run(os.Args); err != nil { + if m.client != nil { + m.client.Disconnect(m.ctx) + } + os.Exit(1) + } +} + +func (m *Migration) Initialize() error { + m.CLI().Usage = "BACK-37: Migrate all existing data to add required Platform deduplication hash fields" + m.CLI().Description = "BACK-37: To fully migrate devices from the `jellyfish` upload API to the `platform` upload API" + m.CLI().Authors = []cli.Author{ + { + Name: "J H BATE", + Email: "jamie@tidepool.org", + }, + } + m.CLI().Flags = append(m.CLI().Flags, + cli.BoolFlag{ + Name: fmt.Sprintf("%s,%s", DryRunFlag, "n"), + Usage: "dry run only; do not migrate", + Destination: &m.config.dryRun, + }, + cli.BoolFlag{ + Name: "stop-error", + Usage: "stop migration on error", + Destination: &m.config.stopOnErr, + }, + cli.Int64Flag{ + Name: "batch-size", + Usage: "number of records to read each time", + Destination: &m.config.readBatchSize, + Value: 300, + Required: false, + }, + cli.IntFlag{ + Name: "min-free-percent", + Usage: "minimum free disk space percent", + Destination: &m.config.minFreePercent, + Value: 10, + Required: false, + }, + cli.IntFlag{ + Name: "nop-percent", + Usage: "how much of the oplog is NOP", + Destination: &m.config.nopPercent, + Value: 50, + Required: false, + }, + cli.StringFlag{ + Name: "uri", + Usage: "mongo connection URI", + Destination: &m.config.uri, + Required: false, + //uri string comes from file called `uri` + FilePath: "./uri", + }, + cli.StringFlag{ + Name: "datum-id", + Usage: "id of last datum updated", + Destination: &m.config.lastUpdatedId, + Required: false, + //id of last datum updated read and written to file `lastUpdatedId` + FilePath: "./lastUpdatedId", + }, + cli.StringFlag{ + Name: "user-id", + Usage: "id of single user to migrate", + Destination: &m.config.userID, + Required: false, + }, + ) + return nil +} + +func (m *Migration) CLI() *cli.App { + return m.cli +} + +func (m *Migration) getDataCollection() *mongo.Collection { + return m.client.Database("data").Collection("deviceData") +} + +func (m *Migration) onError(errToReport error, id string, msg string) { + m.migrationUtil.OnError(errToReport, id, msg) +} + +func (m *Migration) fetchAndUpdateBatch(updates []mongo.WriteModel) bool { + + selector := bson.M{ + "_deduplicator": bson.M{"$exists": false}, + } + + if strings.TrimSpace(m.config.userID) != "" { + log.Printf("fetching for user %s", m.config.userID) + selector["_userId"] = m.config.userID + } + + // jellyfish uses a generated _id that is not an mongo objectId + idNotObjectID := bson.M{"$not": bson.M{"$type": "objectId"}} + + if strings.TrimSpace(m.config.lastUpdatedId) != "" { + selector["$and"] = []interface{}{ + bson.M{"_id": bson.M{"$gt": m.config.lastUpdatedId}}, + bson.M{"_id": idNotObjectID}, + } + } else { + selector["_id"] = idNotObjectID + } + + batchSize := int32(10000) + limit := int64(50000) + + if dataC := m.getDataCollection(); dataC != nil { + fetchStart := time.Now() + + dDataCursor, err := dataC.Find(m.ctx, selector, + &options.FindOptions{ + Sort: bson.M{"_id": 1}, + BatchSize: &batchSize, + Limit: &limit, + }, + ) + if err != nil { + log.Printf("failed to select data: %s", err) + return false + } + + defer dDataCursor.Close(m.ctx) + + log.Printf("1. data fetch [%v] took [%s]", selector, time.Since(fetchStart)) + + updateStart := time.Now() + + for dDataCursor.Next(m.ctx) { + + item := bson.M{} + if err := dDataCursor.Decode(&item); err != nil { + log.Printf("error decoding data: %s", err) + return false + } + + datumID, datumUpdates, err := utils.GetDatumUpdates(item) + if err != nil { + m.onError(err, datumID, "failed getting updates") + continue + } + for _, update := range datumUpdates { + updateOp := mongo.NewUpdateOneModel() + if update["$rename"] != nil { + log.Printf("rename op, 2 ops for same datum") + updateOp.SetFilter(bson.M{"_id": datumID}) + } else { + updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": item["modifiedTime"]}) + } + updateOp.SetUpdate(update) + updates = append(updates, updateOp) + } + m.config.lastUpdatedId = datumID + } + + log.Printf("2. data update took [%s] for [%d] items", time.Since(updateStart), len(updates)) + return len(updates) > 0 + } + return false +} diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index ca38e20939..32451569b9 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -14,7 +14,7 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" ) -type Config struct { +type MigrationUtilConfig struct { //apply no changes dryRun bool //halt on error @@ -35,32 +35,45 @@ type Config struct { type migrationUtil struct { writeBatchSize *int64 client *mongo.Client - config *Config + config *MigrationUtilConfig updates []mongo.WriteModel lastUpdatedId string } +type MigrationUtil interface { + Initialize(ctx context.Context, dataC *mongo.Collection) error + Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func(updates []mongo.WriteModel) bool) error + OnError(reportErr error, id string, msg string) +} + const oplogName = "oplog.rs" // MigrationUtil helps managed the migration process // errors written to -func NewMigrationUtil(client *mongo.Client, config *Config) (*migrationUtil, error) { +func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client) (MigrationUtil, error) { var err error + if config == nil { + err = errors.Join(err, errors.New("missing required configuration")) + } if client == nil { err = errors.Join(err, errors.New("missing required mongo client")) } - if config == nil { - err = errors.Join(err, errors.New("missing required configuration")) + + if err != nil { + return nil, err } + log.Printf("migration util configuration: %v", config) + return &migrationUtil{ client: client, config: config, updates: []mongo.WriteModel{}, - }, err + }, nil } func (m *migrationUtil) Initialize(ctx context.Context, dataC *mongo.Collection) error { + if err := m.checkFreeSpace(ctx, dataC); err != nil { return err } @@ -87,17 +100,60 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe return nil } -func (m *migrationUtil) getOplogCollection() *mongo.Collection { - return m.client.Database("local").Collection(oplogName) +func NewMigrationUtilConfig(dryRun *bool, stopOnErr *bool, nopPercent *int) *MigrationUtilConfig { + cfg := &MigrationUtilConfig{ + minOplogWindow: 28800, // 8hrs + minFreePercent: 10, + expectedOplogEntrySize: 420, + + dryRun: true, + stopOnErr: true, + nopPercent: 25, + } + if dryRun != nil { + cfg.SetDryRun(*dryRun) + } + if stopOnErr != nil { + cfg.SetStopOnErr(*stopOnErr) + } + if nopPercent != nil { + cfg.SetNopPercent(*nopPercent) + } + return cfg } -func (m *migrationUtil) getAdminDB() *mongo.Database { - return m.client.Database("admin") +func (c *MigrationUtilConfig) SetNopPercent(nopPercent int) *MigrationUtilConfig { + c.nopPercent = nopPercent + return c } -func (m *migrationUtil) onError(err error, id string, msg string) { +func (c *MigrationUtilConfig) SetMinOplogWindow(minOplogWindow int) *MigrationUtilConfig { + c.minOplogWindow = minOplogWindow + return c +} +func (c *MigrationUtilConfig) SetExpectedOplogEntrySize(expectedOplogEntrySize int) *MigrationUtilConfig { + c.expectedOplogEntrySize = expectedOplogEntrySize + return c +} +func (c *MigrationUtilConfig) SetMinFreePercent(minFreePercent int) *MigrationUtilConfig { + c.minFreePercent = minFreePercent + return c +} +func (c *MigrationUtilConfig) SetDryRun(dryRun bool) *MigrationUtilConfig { + c.dryRun = dryRun + return c +} +func (c *MigrationUtilConfig) SetStopOnErr(stopOnErr bool) *MigrationUtilConfig { + c.stopOnErr = stopOnErr + return c +} + +// OnError +// - write error to file `error.log` in directory cli is running in +// - optionally stop the operation if stopOnErr is true in the config +func (m *migrationUtil) OnError(reportErr error, id string, msg string) { var errFormat = "[id=%s] %s %s" - if err != nil { + if reportErr != nil { f, err := os.OpenFile("error.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { @@ -105,24 +161,31 @@ func (m *migrationUtil) onError(err error, id string, msg string) { os.Exit(1) } defer f.Close() - f.WriteString(fmt.Sprintf(errFormat, id, msg, err.Error())) + f.WriteString(fmt.Sprintf(errFormat, id, msg, reportErr.Error())) writeLastItemUpdate(m.lastUpdatedId, m.config.dryRun) if m.config.stopOnErr { - log.Printf(errFormat, id, msg, err.Error()) + log.Printf(errFormat, id, msg, reportErr.Error()) os.Exit(1) } } } +func (m *migrationUtil) getOplogCollection() *mongo.Collection { + return m.client.Database("local").Collection(oplogName) +} + +func (m *migrationUtil) getAdminDB() *mongo.Database { + return m.client.Database("admin") +} + func writeLastItemUpdate(itemID string, dryRun bool) { if dryRun { log.Printf("dry run so not setting lastUpdatedId %s", itemID) return } - f, err := os.OpenFile("./lastUpdatedId", - os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + f, err := os.Create("./lastUpdatedId") if err != nil { log.Println(err) os.Exit(1) @@ -298,11 +361,11 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio updateCount := 0 for _, batch := range getBatches(int(*m.writeBatchSize)) { if err := m.blockUntilDBReady(ctx); err != nil { - log.Printf("writeBatchUpdates-blocking error: %s", err) + //log.Printf("writeBatchUpdates-blocking error: %s", err) return updateCount, err } if err := m.checkFreeSpace(ctx, dataC); err != nil { - log.Printf("writeBatchUpdates-freespace error: %s", err) + //log.Printf("writeBatchUpdates-freespace error: %s", err) return updateCount, err } log.Printf("batch size to write %d", len(batch)) From 44533ab0d3d1b691ac82f3768adf40da600ef12a Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 11 Jan 2024 14:42:14 +1300 Subject: [PATCH 103/413] move data to util --- .../jellyfish_migration.go | 17 +++-- .../utils/migrationUtil.go | 65 ++++++++++++------- 2 files changed, 53 insertions(+), 29 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 03c67b5011..908427202b 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -68,9 +68,11 @@ func (m *Migration) RunAndExit() { } defer m.client.Disconnect(m.ctx) + log.Println("## create new migrationUtil") m.migrationUtil, err = utils.NewMigrationUtil( utils.NewMigrationUtilConfig(&m.config.dryRun, &m.config.stopOnErr, &m.config.nopPercent), m.client, + &m.config.lastUpdatedId, ) if err != nil { return fmt.Errorf("unable init migration utils : %w", err) @@ -174,7 +176,9 @@ func (m *Migration) onError(errToReport error, id string, msg string) { m.migrationUtil.OnError(errToReport, id, msg) } -func (m *Migration) fetchAndUpdateBatch(updates []mongo.WriteModel) bool { +func (m *Migration) fetchAndUpdateBatch() bool { + + log.Println("## fetching") selector := bson.M{ "_deduplicator": bson.M{"$exists": false}, @@ -188,9 +192,9 @@ func (m *Migration) fetchAndUpdateBatch(updates []mongo.WriteModel) bool { // jellyfish uses a generated _id that is not an mongo objectId idNotObjectID := bson.M{"$not": bson.M{"$type": "objectId"}} - if strings.TrimSpace(m.config.lastUpdatedId) != "" { + if lastID := m.migrationUtil.GetLastID(); lastID != "" { selector["$and"] = []interface{}{ - bson.M{"_id": bson.M{"$gt": m.config.lastUpdatedId}}, + bson.M{"_id": bson.M{"$gt": lastID}}, bson.M{"_id": idNotObjectID}, } } else { @@ -243,13 +247,12 @@ func (m *Migration) fetchAndUpdateBatch(updates []mongo.WriteModel) bool { updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": item["modifiedTime"]}) } updateOp.SetUpdate(update) - updates = append(updates, updateOp) + m.migrationUtil.SetData(updateOp, datumID) } - m.config.lastUpdatedId = datumID } - log.Printf("2. data update took [%s] for [%d] items", time.Since(updateStart), len(updates)) - return len(updates) > 0 + log.Printf("2. data update took [%s] for [%d] items", time.Since(updateStart), m.migrationUtil.GetUpdatesCount()) + return m.migrationUtil.GetUpdatesCount() > 0 } return false } diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 32451569b9..ef184abe78 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -7,6 +7,7 @@ import ( "log" "math" "os" + "strings" "time" "go.mongodb.org/mongo-driver/bson" @@ -42,15 +43,18 @@ type migrationUtil struct { type MigrationUtil interface { Initialize(ctx context.Context, dataC *mongo.Collection) error - Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func(updates []mongo.WriteModel) bool) error + Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func() bool) error OnError(reportErr error, id string, msg string) + SetData(update *mongo.UpdateOneModel, lastID string) + GetLastID() string + GetUpdatesCount() int } const oplogName = "oplog.rs" // MigrationUtil helps managed the migration process // errors written to -func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client) (MigrationUtil, error) { +func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client, lastID *string) (MigrationUtil, error) { var err error if config == nil { err = errors.Join(err, errors.New("missing required configuration")) @@ -65,15 +69,19 @@ func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client) (Migrat log.Printf("migration util configuration: %v", config) - return &migrationUtil{ + m := &migrationUtil{ client: client, config: config, updates: []mongo.WriteModel{}, - }, nil + } + if lastID != nil { + m.lastUpdatedId = *lastID + } + return m, nil } func (m *migrationUtil) Initialize(ctx context.Context, dataC *mongo.Collection) error { - + log.Print("Initialize migrationUtil") if err := m.checkFreeSpace(ctx, dataC); err != nil { return err } @@ -83,10 +91,10 @@ func (m *migrationUtil) Initialize(ctx context.Context, dataC *mongo.Collection) return nil } -func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func(updates []mongo.WriteModel) bool) error { +func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func() bool) error { totalMigrated := 0 migrateStart := time.Now() - for fetchAndUpdateFn(m.updates) { + for fetchAndUpdateFn() { writeStart := time.Now() updatedCount, err := m.writeUpdates(ctx, dataC) if err != nil { @@ -100,6 +108,20 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe return nil } +func (m *migrationUtil) SetData(update *mongo.UpdateOneModel, lastID string) { + log.Printf("last id [%s] now [%s]", m.lastUpdatedId, lastID) + m.lastUpdatedId = lastID + m.updates = append(m.updates, update) +} + +func (m *migrationUtil) GetUpdatesCount() int { + return len(m.updates) +} + +func (m *migrationUtil) GetLastID() string { + return m.lastUpdatedId +} + func NewMigrationUtilConfig(dryRun *bool, stopOnErr *bool, nopPercent *int) *MigrationUtilConfig { cfg := &MigrationUtilConfig{ minOplogWindow: 28800, // 8hrs @@ -162,9 +184,6 @@ func (m *migrationUtil) OnError(reportErr error, id string, msg string) { } defer f.Close() f.WriteString(fmt.Sprintf(errFormat, id, msg, reportErr.Error())) - - writeLastItemUpdate(m.lastUpdatedId, m.config.dryRun) - if m.config.stopOnErr { log.Printf(errFormat, id, msg, reportErr.Error()) os.Exit(1) @@ -181,17 +200,19 @@ func (m *migrationUtil) getAdminDB() *mongo.Database { } func writeLastItemUpdate(itemID string, dryRun bool) { - if dryRun { - log.Printf("dry run so not setting lastUpdatedId %s", itemID) - return - } - f, err := os.Create("./lastUpdatedId") - if err != nil { - log.Println(err) - os.Exit(1) + if strings.TrimSpace(itemID) != "" { + if dryRun { + log.Printf("dry run so not setting lastUpdatedId %s", itemID) + return + } + f, err := os.Create("./lastUpdatedId") + if err != nil { + log.Println(err) + os.Exit(1) + } + defer f.Close() + f.WriteString(itemID) } - defer f.Close() - f.WriteString(itemID) } func (m *migrationUtil) getOplogDuration(ctx context.Context) (time.Duration, error) { @@ -344,8 +365,6 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio if len(m.updates) == 0 { return 0, nil } - - writeLastItemUpdate(m.lastUpdatedId, m.config.dryRun) start := time.Now() var getBatches = func(chunkSize int) [][]mongo.WriteModel { batches := [][]mongo.WriteModel{} @@ -380,7 +399,9 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio log.Printf("error writing batch updates %v", err) return updateCount, err } + updateCount += int(results.ModifiedCount) + writeLastItemUpdate(m.lastUpdatedId, m.config.dryRun) } log.Printf("mongo bulk write took %s", time.Since(start)) return updateCount, nil From 73a892df5d22c706515eb263f1670da5041a7005 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 11 Jan 2024 15:06:07 +1300 Subject: [PATCH 104/413] set a cap for number of items to migrate --- .../jellyfish_migration.go | 3 ++- .../utils/migrationUtil.go | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 908427202b..5278ca4bc1 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -69,8 +69,9 @@ func (m *Migration) RunAndExit() { defer m.client.Disconnect(m.ctx) log.Println("## create new migrationUtil") + cap := 50000 // while testing m.migrationUtil, err = utils.NewMigrationUtil( - utils.NewMigrationUtilConfig(&m.config.dryRun, &m.config.stopOnErr, &m.config.nopPercent), + utils.NewMigrationUtilConfig(&m.config.dryRun, &m.config.stopOnErr, &m.config.nopPercent, &cap), m.client, &m.config.lastUpdatedId, ) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index ef184abe78..03b831ed06 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -31,6 +31,8 @@ type MigrationUtilConfig struct { nopPercent int // minimum free disk space percent minFreePercent int + // cap for number of items to migrate + cap *int } type migrationUtil struct { @@ -103,13 +105,18 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe } log.Printf("4. data write took [%s] for [%d] items", time.Since(writeStart), updatedCount) totalMigrated = totalMigrated + updatedCount + + if m.config.cap != nil { + if totalMigrated >= *m.config.cap { + break + } + } } log.Printf("migration took [%s] for [%d] items ", time.Since(migrateStart), totalMigrated) return nil } func (m *migrationUtil) SetData(update *mongo.UpdateOneModel, lastID string) { - log.Printf("last id [%s] now [%s]", m.lastUpdatedId, lastID) m.lastUpdatedId = lastID m.updates = append(m.updates, update) } @@ -122,7 +129,7 @@ func (m *migrationUtil) GetLastID() string { return m.lastUpdatedId } -func NewMigrationUtilConfig(dryRun *bool, stopOnErr *bool, nopPercent *int) *MigrationUtilConfig { +func NewMigrationUtilConfig(dryRun *bool, stopOnErr *bool, nopPercent *int, cap *int) *MigrationUtilConfig { cfg := &MigrationUtilConfig{ minOplogWindow: 28800, // 8hrs minFreePercent: 10, @@ -141,6 +148,9 @@ func NewMigrationUtilConfig(dryRun *bool, stopOnErr *bool, nopPercent *int) *Mig if nopPercent != nil { cfg.SetNopPercent(*nopPercent) } + if cap != nil { + cfg.cap = cap + } return cfg } From 3a55dc252093176383d5e0d6c1a7ac3300382a77 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 11 Jan 2024 15:15:21 +1300 Subject: [PATCH 105/413] remove noise --- .../utils/migrationUtil.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 03b831ed06..ae1c7f3cdc 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -107,12 +107,16 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe totalMigrated = totalMigrated + updatedCount if m.config.cap != nil { + log.Println("check cap") if totalMigrated >= *m.config.cap { break } } } log.Printf("migration took [%s] for [%d] items ", time.Since(migrateStart), totalMigrated) + if m.config.dryRun { + log.Println("dry-run so no changes applied") + } return nil } @@ -246,7 +250,6 @@ func (m *migrationUtil) getOplogDuration(ctx context.Context) (time.Duration, er return 0, err } oplogDuration := newest.Wall.Sub(oldest.Wall) - log.Printf("current oplog duration: %v", oplogDuration) return oplogDuration, nil } log.Println("Not clustered, not retrieving oplog duration.") @@ -296,7 +299,6 @@ func (m *migrationUtil) checkFreeSpace(ctx context.Context, dataC *mongo.Collect } bytesFree := metaData.FsTotalSize - metaData.FsUsedSize percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) - log.Printf("DB disk currently has %d%% (%d bytes) free.", percentFree, bytesFree) if m.config.minFreePercent > percentFree { return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) } @@ -390,18 +392,14 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio updateCount := 0 for _, batch := range getBatches(int(*m.writeBatchSize)) { if err := m.blockUntilDBReady(ctx); err != nil { - //log.Printf("writeBatchUpdates-blocking error: %s", err) return updateCount, err } if err := m.checkFreeSpace(ctx, dataC); err != nil { - //log.Printf("writeBatchUpdates-freespace error: %s", err) return updateCount, err } - log.Printf("batch size to write %d", len(batch)) if m.config.dryRun { updateCount += len(batch) - log.Println("dry run so not applying changes") continue } results, err := dataC.BulkWrite(ctx, batch) From 9d2daab3b95f07b6196ba23664b0ff1183e1b0b3 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 11 Jan 2024 16:02:41 +1300 Subject: [PATCH 106/413] configure cap --- .../jellyfish_migration.go | 31 +++++++------------ .../utils/migrationUtil.go | 11 +++---- 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 5278ca4bc1..dbe5269f0e 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -25,14 +25,13 @@ type Migration struct { } type config struct { - uri string - dryRun bool - stopOnErr bool - userID string - lastUpdatedId string - minFreePercent int - nopPercent int - readBatchSize int64 + cap int + uri string + dryRun bool + stopOnErr bool + userID string + lastUpdatedId string + nopPercent int } const DryRunFlag = "dry-run" @@ -69,7 +68,7 @@ func (m *Migration) RunAndExit() { defer m.client.Disconnect(m.ctx) log.Println("## create new migrationUtil") - cap := 50000 // while testing + cap := m.config.cap // while testing m.migrationUtil, err = utils.NewMigrationUtil( utils.NewMigrationUtilConfig(&m.config.dryRun, &m.config.stopOnErr, &m.config.nopPercent, &cap), m.client, @@ -118,18 +117,10 @@ func (m *Migration) Initialize() error { Usage: "stop migration on error", Destination: &m.config.stopOnErr, }, - cli.Int64Flag{ - Name: "batch-size", - Usage: "number of records to read each time", - Destination: &m.config.readBatchSize, - Value: 300, - Required: false, - }, cli.IntFlag{ - Name: "min-free-percent", - Usage: "minimum free disk space percent", - Destination: &m.config.minFreePercent, - Value: 10, + Name: "cap", + Usage: "max number of records migrate", + Destination: &m.config.cap, Required: false, }, cli.IntFlag{ diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index ae1c7f3cdc..0f8a9b581c 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -69,8 +69,6 @@ func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client, lastID return nil, err } - log.Printf("migration util configuration: %v", config) - m := &migrationUtil{ client: client, config: config, @@ -83,7 +81,6 @@ func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client, lastID } func (m *migrationUtil) Initialize(ctx context.Context, dataC *mongo.Collection) error { - log.Print("Initialize migrationUtil") if err := m.checkFreeSpace(ctx, dataC); err != nil { return err } @@ -96,6 +93,7 @@ func (m *migrationUtil) Initialize(ctx context.Context, dataC *mongo.Collection) func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func() bool) error { totalMigrated := 0 migrateStart := time.Now() + for fetchAndUpdateFn() { writeStart := time.Now() updatedCount, err := m.writeUpdates(ctx, dataC) @@ -105,9 +103,7 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe } log.Printf("4. data write took [%s] for [%d] items", time.Since(writeStart), updatedCount) totalMigrated = totalMigrated + updatedCount - if m.config.cap != nil { - log.Println("check cap") if totalMigrated >= *m.config.cap { break } @@ -152,8 +148,9 @@ func NewMigrationUtilConfig(dryRun *bool, stopOnErr *bool, nopPercent *int, cap if nopPercent != nil { cfg.SetNopPercent(*nopPercent) } - if cap != nil { + if cap != nil && *cap > 0 { cfg.cap = cap + log.Printf("capped at %d items") } return cfg } @@ -188,7 +185,7 @@ func (c *MigrationUtilConfig) SetStopOnErr(stopOnErr bool) *MigrationUtilConfig // - write error to file `error.log` in directory cli is running in // - optionally stop the operation if stopOnErr is true in the config func (m *migrationUtil) OnError(reportErr error, id string, msg string) { - var errFormat = "[id=%s] %s %s" + var errFormat = "[id=%s] %s %s\n" if reportErr != nil { f, err := os.OpenFile("error.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) From 9891448598ae5e08ad2de05b0faeb3051c52eae5 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 11 Jan 2024 16:10:29 +1300 Subject: [PATCH 107/413] debug --- migrations/20231128_jellyfish_migration/utils/migrationUtil.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 0f8a9b581c..8fe859cba3 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -150,7 +150,7 @@ func NewMigrationUtilConfig(dryRun *bool, stopOnErr *bool, nopPercent *int, cap } if cap != nil && *cap > 0 { cfg.cap = cap - log.Printf("capped at %d items") + log.Printf("capped at %d items", *cfg.cap) } return cfg } From 89cf04fb6d531c77dfd3cd0a78a72959f025f04f Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 11 Jan 2024 16:27:28 +1300 Subject: [PATCH 108/413] attempt bulk decode to see if faster --- .../jellyfish_migration.go | 17 ++++++----------- .../utils/migrationUtil.go | 2 -- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index dbe5269f0e..cab5a214ec 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -66,8 +66,6 @@ func (m *Migration) RunAndExit() { return fmt.Errorf("unable to connect to MongoDB: %w", err) } defer m.client.Disconnect(m.ctx) - - log.Println("## create new migrationUtil") cap := m.config.cap // while testing m.migrationUtil, err = utils.NewMigrationUtil( utils.NewMigrationUtilConfig(&m.config.dryRun, &m.config.stopOnErr, &m.config.nopPercent, &cap), @@ -170,8 +168,6 @@ func (m *Migration) onError(errToReport error, id string, msg string) { func (m *Migration) fetchAndUpdateBatch() bool { - log.Println("## fetching") - selector := bson.M{ "_deduplicator": bson.M{"$exists": false}, } @@ -217,14 +213,13 @@ func (m *Migration) fetchAndUpdateBatch() bool { updateStart := time.Now() - for dDataCursor.Next(m.ctx) { - - item := bson.M{} - if err := dDataCursor.Decode(&item); err != nil { - log.Printf("error decoding data: %s", err) - return false - } + results := []bson.M{} + if err := dDataCursor.All(m.ctx, &results); err != nil { + log.Printf("decoding find results: %s", err) + return false + } + for _, item := range results { datumID, datumUpdates, err := utils.GetDatumUpdates(item) if err != nil { m.onError(err, datumID, "failed getting updates") diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 8fe859cba3..0a373e6b15 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -374,7 +374,6 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio if len(m.updates) == 0 { return 0, nil } - start := time.Now() var getBatches = func(chunkSize int) [][]mongo.WriteModel { batches := [][]mongo.WriteModel{} for i := 0; i < len(m.updates); i += chunkSize { @@ -408,6 +407,5 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio updateCount += int(results.ModifiedCount) writeLastItemUpdate(m.lastUpdatedId, m.config.dryRun) } - log.Printf("mongo bulk write took %s", time.Since(start)) return updateCount, nil } From d00b3cdf840614f869866aa2b0f2f6c560aee6dc Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 15 Jan 2024 09:29:19 +1300 Subject: [PATCH 109/413] iterate each item --- .../jellyfish_migration.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index cab5a214ec..82e0824a85 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -213,13 +213,14 @@ func (m *Migration) fetchAndUpdateBatch() bool { updateStart := time.Now() - results := []bson.M{} - if err := dDataCursor.All(m.ctx, &results); err != nil { - log.Printf("decoding find results: %s", err) - return false - } + for dDataCursor.Next(m.ctx) { + + item := bson.M{} + if err := dDataCursor.Decode(&item); err != nil { + log.Printf("error decoding data: %s", err) + return false + } - for _, item := range results { datumID, datumUpdates, err := utils.GetDatumUpdates(item) if err != nil { m.onError(err, datumID, "failed getting updates") From bb045fa3173c1aa27cd32d68c1aaa5d972d50b2c Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 16 Jan 2024 13:40:43 +1300 Subject: [PATCH 110/413] updates and tests based on trial migrations --- .../20231128_jellyfish_migration.go | 535 ------------------ .../jellyfish_migration.go | 1 + .../utils/migrationUtil.go | 6 +- .../utils/test/data.go | 159 ++++++ .../utils/utils.go | 4 + .../utils/utils_test.go | 38 ++ 6 files changed, 204 insertions(+), 539 deletions(-) delete mode 100644 migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go create mode 100644 migrations/20231128_jellyfish_migration/utils/test/data.go diff --git a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go b/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go deleted file mode 100644 index 44fb7e55e4..0000000000 --- a/migrations/20231128_jellyfish_migration/20231128_jellyfish_migration.go +++ /dev/null @@ -1,535 +0,0 @@ -package main - -// import ( -// "context" -// "errors" -// "fmt" -// "log" -// "math" -// "os" -// "strings" -// "time" - -// "github.com/urfave/cli" -// "go.mongodb.org/mongo-driver/bson" -// "go.mongodb.org/mongo-driver/mongo" -// "go.mongodb.org/mongo-driver/mongo/options" - -// "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" -// ) - -// type Config struct { -// uri string -// minOplogWindow int -// // these values are used to determine writes batches, first dividing the oplog's size with the desired duration and -// // expected entry size, then adding a divisor to account for NOP overshoot in the oplog -// expectedOplogEntrySize int -// // how much of the oplog is NOP, this adjusts the batch to account for an oplog that is very change sensitive -// // must be > 0 -// // prod 0.6 -// // idle 100 -// nopPercent int -// // minimum free disk space percent -// minFreePercent int -// readBatchSize int64 -// } - -// type Migration struct { -// ctx context.Context -// cli *cli.App -// config *Config -// client *mongo.Client -// writeBatchSize *int64 -// updates []mongo.WriteModel -// dryRun bool -// stopOnErr bool -// userID string -// lastUpdatedId string -// } - -// const oplogName = "oplog.rs" -// const DryRunFlag = "dry-run" - -// func main() { -// ctx := context.Background() -// ctx, cancel := context.WithCancel(ctx) -// defer cancel() -// migration := NewMigration(ctx) -// migration.RunAndExit() -// log.Println("finished migration") -// } - -// func NewMigration(ctx context.Context) *Migration { -// return &Migration{ -// ctx: ctx, -// cli: cli.NewApp(), -// config: &Config{}, -// updates: []mongo.WriteModel{}, -// stopOnErr: false, -// } -// } - -// func (m *Migration) RunAndExit() { -// if err := m.Initialize(); err != nil { -// os.Exit(1) -// } - -// m.CLI().Action = func(ctx *cli.Context) error { -// var err error -// m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(strings.TrimSpace(m.config.uri))) -// if err != nil { -// return fmt.Errorf("unable to connect to MongoDB: %w", err) -// } -// defer m.client.Disconnect(m.ctx) -// if err := m.prepare(); err != nil { -// log.Printf("prepare failed: %s", err) -// return err -// } -// if err := m.execute(); err != nil { -// log.Printf("execute failed: %s", err) -// return err -// } -// return nil -// } - -// log.Printf("args %v", os.Args) - -// if err := m.CLI().Run(os.Args); err != nil { -// if m.client != nil { -// m.client.Disconnect(m.ctx) -// } -// os.Exit(1) -// } -// } - -// func (m *Migration) Initialize() error { -// m.CLI().Usage = "BACK-37: Migrate all existing data to add required Platform deduplication hash fields" -// m.CLI().Description = "BACK-37: To fully migrate devices from the `jellyfish` upload API to the `platform` upload API" -// m.CLI().Authors = []cli.Author{ -// { -// Name: "J H BATE", -// Email: "jamie@tidepool.org", -// }, -// } -// m.CLI().Flags = append(m.CLI().Flags, -// cli.BoolFlag{ -// Name: fmt.Sprintf("%s,%s", DryRunFlag, "n"), -// Usage: "dry run only; do not migrate", -// Destination: &m.dryRun, -// }, -// cli.BoolFlag{ -// Name: "stop-error", -// Usage: "stop migration on error", -// Destination: &m.stopOnErr, -// }, -// cli.Int64Flag{ -// Name: "batch-size", -// Usage: "number of records to read each time", -// Destination: &m.config.readBatchSize, -// Value: 300, -// Required: false, -// }, -// cli.IntFlag{ -// Name: "min-free-percent", -// Usage: "minimum free disk space percent", -// Destination: &m.config.minFreePercent, -// Value: 10, -// Required: false, -// }, -// cli.IntFlag{ -// Name: "nop-percent", -// Usage: "how much of the oplog is NOP", -// Destination: &m.config.nopPercent, -// Value: 50, -// Required: false, -// }, -// cli.IntFlag{ -// Name: "oplog-entry-size", -// Usage: "expected oplog entry size", -// Destination: &m.config.expectedOplogEntrySize, -// Value: 420, -// Required: false, -// }, -// cli.IntFlag{ -// Name: "oplog-window", -// Usage: "minimum oplog window in seconds", -// Destination: &m.config.minOplogWindow, -// Value: 28800, // 8hrs -// Required: false, -// }, -// cli.StringFlag{ -// Name: "uri", -// Usage: "mongo connection URI", -// Destination: &m.config.uri, -// Required: false, -// //uri string comes from file called `uri` -// FilePath: "./uri", -// }, -// cli.StringFlag{ -// Name: "datum-id", -// Usage: "id of last datum updated", -// Destination: &m.lastUpdatedId, -// Required: false, -// //id of last datum updated read and written to file `lastUpdatedId` -// FilePath: "./lastUpdatedId", -// }, -// cli.StringFlag{ -// Name: "user-id", -// Usage: "id of single user to migrate", -// Destination: &m.userID, -// Required: false, -// }, -// ) -// return nil -// } - -// func (m *Migration) CLI() *cli.App { -// return m.cli -// } - -// func (m *Migration) getDataCollection() *mongo.Collection { -// return m.client.Database("data").Collection("deviceData") -// } - -// func (m *Migration) getOplogCollection() *mongo.Collection { -// return m.client.Database("local").Collection(oplogName) -// } - -// func (m *Migration) onError(errToReport error, id string, msg string) { -// if errToReport != nil { -// var errFormat = "[id=%s] %s %s\n" -// f, err := os.OpenFile("error.log", -// os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) -// if err != nil { -// log.Println(err) -// os.Exit(1) -// } -// defer f.Close() -// f.WriteString(fmt.Sprintf(errFormat, id, msg, errToReport.Error())) -// writeLastItemUpdate(m.lastUpdatedId, m.dryRun) -// if m.stopOnErr { -// log.Printf(errFormat, id, msg, errToReport.Error()) -// os.Exit(1) -// } -// } -// } - -// func writeLastItemUpdate(itemID string, dryRun bool) { -// if strings.TrimSpace(itemID) == "" { -// return -// } -// if dryRun { -// log.Printf("dry run so not setting lastUpdatedId %s", itemID) -// return -// } -// f, err := os.Create("./lastUpdatedId") -// if err != nil { -// log.Println(err) -// os.Exit(1) -// } -// defer f.Close() -// f.WriteString(itemID) -// } - -// func (m *Migration) prepare() error { -// if err := m.checkFreeSpace(); err != nil { -// return err -// } -// if err := m.setWriteBatchSize(); err != nil { -// return err -// } -// return nil -// } - -// func (m *Migration) execute() error { -// totalMigrated := 0 -// migrateStart := time.Now() -// for m.fetchAndUpdateBatch() { -// writeStart := time.Now() -// updatedCount, err := m.writeBatchUpdates() -// if err != nil { -// log.Printf("failed writing batch: %s", err) -// return err -// } -// log.Printf("3. write took [%s] for [%d] items", time.Since(writeStart), updatedCount) -// totalMigrated = totalMigrated + updatedCount -// if totalMigrated > 500000 { -// log.Println("quitting after 500K records") -// break -// } -// } -// log.Printf("migration completed in [%s] for [%d] items ", time.Since(migrateStart), totalMigrated) -// if m.dryRun { -// log.Println("no updates applied as run as a dry-run") -// } -// return nil -// } - -// func (m *Migration) getOplogDuration() (time.Duration, error) { -// type MongoMetaData struct { -// Wall time.Time `json:"wall"` -// } -// if oplogC := m.getOplogCollection(); oplogC != nil { -// var oldest MongoMetaData -// if err := oplogC.FindOne( -// m.ctx, -// bson.M{"wall": bson.M{"$exists": true}}, -// options.FindOne().SetSort(bson.M{"$natural": 1})).Decode(&oldest); err != nil { -// return 0, err -// } - -// var newest MongoMetaData -// if err := oplogC.FindOne( -// m.ctx, -// bson.M{"wall": bson.M{"$exists": true}}, -// options.FindOne().SetSort(bson.M{"$natural": -1})).Decode(&newest); err != nil { -// return 0, err -// } -// oplogDuration := newest.Wall.Sub(oldest.Wall) -// return oplogDuration, nil -// } -// log.Println("Not clustered, not retrieving oplog duration.") -// oplogDuration := time.Duration(m.config.minOplogWindow+1) * time.Second -// return oplogDuration, nil - -// } - -// func (m *Migration) setWriteBatchSize() error { -// // pass in config and mongo oplog collection - -// var calculateBatchSize = func(oplogSize int, oplogEntryBytes int, oplogMinWindow int, nopPercent int) int64 { -// return int64(math.Floor(float64(oplogSize) / float64(oplogEntryBytes) / float64(oplogMinWindow) / (float64(nopPercent) / 7))) -// } - -// if oplogC := m.getOplogCollection(); oplogC != nil { -// type MongoMetaData struct { -// MaxSize int `json:"maxSize"` -// } -// var metaData MongoMetaData -// if err := oplogC.Database().RunCommand(m.ctx, bson.M{"collStats": oplogName}).Decode(&metaData); err != nil { -// return err -// } -// writeBatchSize := calculateBatchSize(metaData.MaxSize, m.config.expectedOplogEntrySize, m.config.minOplogWindow, m.config.nopPercent) -// m.writeBatchSize = &writeBatchSize -// log.Printf("calculated writeBatchSize: %d", writeBatchSize) -// return nil -// } -// var writeBatchSize = int64(30000) -// log.Printf("MongoDB is not clustered, removing write batch limit, setting to %d documents.", writeBatchSize) -// m.writeBatchSize = &writeBatchSize -// return nil -// } - -// func (m *Migration) checkFreeSpace() error { -// // pass in config and mongo collection being migrated - -// type MongoMetaData struct { -// FsTotalSize int `json:"fsTotalSize"` -// FsUsedSize int `json:"fsUsedSize"` -// } -// var metaData MongoMetaData -// if dataC := m.getDataCollection(); dataC != nil { -// if err := dataC.Database().RunCommand(m.ctx, bson.M{"dbStats": 1}).Decode(&metaData); err != nil { -// return err -// } -// bytesFree := metaData.FsTotalSize - metaData.FsUsedSize -// percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) -// if m.config.minFreePercent > percentFree { -// return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) -// } -// return nil -// } -// return errors.New("could not get deviceData database") -// } - -// func (m *Migration) getWaitTime() (float64, error) { -// // pass config and mongo admin db -// type Member struct { -// Name string `json:"name"` -// Health int `json:"health"` -// Uptime int `json:"uptime"` -// State int `json:"state"` -// } - -// type MongoMetaData struct { -// Members []Member `json:"members"` -// } - -// var metaData MongoMetaData -// if err := m.client.Database("admin").RunCommand(m.ctx, bson.M{"replSetGetStatus": 1}).Decode(&metaData); err != nil { -// return 0, err -// } - -// for _, member := range metaData.Members { -// if member.State < 1 || member.State > 2 || member.Health != 1 || member.Uptime < 120 { -// log.Printf("DB member %s down or not ready.", member.Name) -// return 240, nil -// } -// } - -// oplogDuration, err := m.getOplogDuration() -// if err != nil { -// return 0, err -// } -// if oplogDuration.Seconds() < float64(m.config.minOplogWindow) { -// minOplogWindowTime := time.Duration(m.config.minOplogWindow) * time.Second -// log.Printf("DB oplog shorter than requested duration of %s, currently %s.", minOplogWindowTime, oplogDuration) -// waitTime := float64(m.config.minOplogWindow) - oplogDuration.Seconds() -// waitTime *= 1.15 -// if waitTime < 600 { -// waitTime = 600 -// } -// return waitTime, nil -// } -// return 0, nil -// } - -// func (m *Migration) blockUntilDBReady() error { -// waitTime, err := m.getWaitTime() -// if err != nil { -// return err -// } -// var totalWait float64 -// for waitTime > 0 { -// totalWait += waitTime -// if totalWait > 1800 { -// log.Printf("Long total wait of %s, possibly high load, or sustained DB outage. If neither, adjust NOP_PERCENT to reduce overshoot.", time.Duration(totalWait)*time.Second) -// } -// log.Printf("Sleeping for %d", time.Duration(waitTime)*time.Second) -// time.Sleep(time.Duration(waitTime) * time.Second) -// waitTime, err = m.getWaitTime() -// if err != nil { -// log.Printf("failed getting wait time %d", time.Duration(waitTime)*time.Second) -// return err -// } -// } -// return nil -// } - -// func (m *Migration) fetchAndUpdateBatch() bool { - -// selector := bson.M{ -// "_deduplicator": bson.M{"$exists": false}, -// } - -// if strings.TrimSpace(m.userID) != "" { -// log.Printf("fetching for user %s", m.userID) -// selector["_userId"] = m.userID -// } - -// // jellyfish uses a generated _id that is not an mongo objectId -// idNotObjectID := bson.M{"$not": bson.M{"$type": "objectId"}} - -// if strings.TrimSpace(m.lastUpdatedId) != "" { -// selector["$and"] = []interface{}{ -// bson.M{"_id": bson.M{"$gt": m.lastUpdatedId}}, -// bson.M{"_id": idNotObjectID}, -// } -// } else { -// selector["_id"] = idNotObjectID -// } - -// m.updates = []mongo.WriteModel{} - -// // TODO: balance with batch write batchSize?? - -// batchSize := int32(10000) -// limit := int64(50000) - -// if dataC := m.getDataCollection(); dataC != nil { -// fetchStart := time.Now() - -// dDataCursor, err := dataC.Find(m.ctx, selector, -// &options.FindOptions{ -// Sort: bson.M{"_id": 1}, -// BatchSize: &batchSize, -// Limit: &limit, -// }, -// ) -// if err != nil { -// log.Printf("failed to select data: %s", err) -// return false -// } - -// defer dDataCursor.Close(m.ctx) - -// log.Printf("1. data fetch [%v] took [%s]", selector, time.Since(fetchStart)) - -// updateStart := time.Now() - -// for dDataCursor.Next(m.ctx) { - -// item := bson.M{} -// if err := dDataCursor.Decode(&item); err != nil { -// log.Printf("error decoding data: %s", err) -// return false -// } - -// datumID, datumUpdates, err := utils.GetDatumUpdates(item) -// if err != nil { -// m.onError(err, datumID, "failed getting updates") -// continue -// } -// for _, update := range datumUpdates { -// updateOp := mongo.NewUpdateOneModel() -// if update["$rename"] != nil { -// log.Printf("rename op, 2 ops for same datum") -// updateOp.SetFilter(bson.M{"_id": datumID}) -// } else { -// updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": item["modifiedTime"]}) -// } -// updateOp.SetUpdate(update) -// m.updates = append(m.updates, updateOp) -// } -// m.lastUpdatedId = datumID -// } - -// log.Printf("2. data update took [%s] for [%d] items", time.Since(updateStart), len(m.updates)) -// return len(m.updates) > 0 -// } -// return false -// } - -// func (m *Migration) writeBatchUpdates() (int, error) { -// if len(m.updates) == 0 { -// return 0, nil -// } -// writeLastItemUpdate(m.lastUpdatedId, m.dryRun) -// var getBatches = func(chunkSize int) [][]mongo.WriteModel { -// batches := [][]mongo.WriteModel{} -// for i := 0; i < len(m.updates); i += chunkSize { -// end := i + chunkSize -// if end > len(m.updates) { -// end = len(m.updates) -// } -// batches = append(batches, m.updates[i:end]) -// } -// return batches -// } -// updateCount := 0 -// for _, batch := range getBatches(int(*m.writeBatchSize)) { -// if err := m.blockUntilDBReady(); err != nil { -// log.Printf("writeBatchUpdates-blocking error: %s", err) -// return updateCount, err -// } -// if err := m.checkFreeSpace(); err != nil { -// log.Printf("writeBatchUpdates-freespace error: %s", err) -// return updateCount, err -// } - -// if m.dryRun { -// updateCount += len(batch) -// continue -// } - -// if deviceC := m.getDataCollection(); deviceC != nil { -// results, err := deviceC.BulkWrite(m.ctx, batch) -// if err != nil { -// log.Printf("error writing batch updates %v", err) -// return updateCount, err -// } -// updateCount += int(results.ModifiedCount) -// } -// } -// return updateCount, nil -// } diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 82e0824a85..53bf10df3b 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -66,6 +66,7 @@ func (m *Migration) RunAndExit() { return fmt.Errorf("unable to connect to MongoDB: %w", err) } defer m.client.Disconnect(m.ctx) + //TODO: just capping while doing test runs, but probably good to have as a general ability cap := m.config.cap // while testing m.migrationUtil, err = utils.NewMigrationUtil( utils.NewMigrationUtilConfig(&m.config.dryRun, &m.config.stopOnErr, &m.config.nopPercent, &cap), diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 0a373e6b15..3948a95ed1 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -52,8 +52,6 @@ type MigrationUtil interface { GetUpdatesCount() int } -const oplogName = "oplog.rs" - // MigrationUtil helps managed the migration process // errors written to func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client, lastID *string) (MigrationUtil, error) { @@ -203,7 +201,7 @@ func (m *migrationUtil) OnError(reportErr error, id string, msg string) { } func (m *migrationUtil) getOplogCollection() *mongo.Collection { - return m.client.Database("local").Collection(oplogName) + return m.client.Database("local").Collection("oplog.rs") } func (m *migrationUtil) getAdminDB() *mongo.Database { @@ -265,7 +263,7 @@ func (m *migrationUtil) setWriteBatchSize(ctx context.Context) error { MaxSize int `json:"maxSize"` } var metaData MongoMetaData - if err := oplogC.Database().RunCommand(ctx, bson.M{"collStats": oplogName}).Decode(&metaData); err != nil { + if err := oplogC.Database().RunCommand(ctx, bson.M{"collStats": "oplog.rs"}).Decode(&metaData); err != nil { return err } writeBatchSize := calculateBatchSize(metaData.MaxSize, m.config.expectedOplogEntrySize, m.config.minOplogWindow, m.config.nopPercent) diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go new file mode 100644 index 0000000000..1fd8ce88d2 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/utils/test/data.go @@ -0,0 +1,159 @@ +package test + +func base(deviceID string) map[string]interface{} { + return map[string]interface{}{ + "_id": "17dbokav5t6pssjv72gm0nie3u25b54m", + "deviceId": deviceID, + "deviceTime": "2017-11-05T12:56:51", + "id": "3f0075ad57ad603c83dc1e1a76aefcaf", + "localTime": "2017-11-05T12:56:51.000Z", + "_userId": "87df73fd41", + "_groupId": "8da6e693b8", + "createdTime": "2022-06-21T22:40:07.732+00:00", + "_version": 0, + "_active": true, + "uploadId": "a21c82a5f5d2860add2539acded6b614", + "time": "2022-06-21T22:40:07.732+00:00", + } +} + +// annotations and payload as a string rather than object or array +func dexG5MobDatum() map[string]interface{} { + datum := base("DexG5Mob_iPhone") + datum["annotations"] = `[{"code":"bg/out-of-range","threshold":40,"value":"low"}]` + datum["payload"] = `{\"systemTime\":\"2017-11-05T18:56:51Z\",\"transmitterId\":\"410X6M\",\"transmitterTicks\":5796922,\"trend\":\"flat\",\"trendRate\":0.6,\"trendRateUnits\":\"mg/dL/min\"}` + datum["type"] = "cbg" + datum["units"] = "mmol/L" + datum["value"] = 8.1596 + return datum +} + +func tandemPumpSettingsDatum() map[string]interface{} { + datum := base("tandem99999999") + + datum["type"] = "pumpSettings" + datum["activeSchedule"] = "Simple" + datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mg/dL"} + datum["basalSchedules"] = map[string]interface{}{ + "Simple": []map[string]interface{}{ + {"rate": 0.5, "start": 0}, + {"rate": 1.35, "start": 55800000}, + }, + "Standard": []map[string]interface{}{ + {"rate": 0.5, "start": 0}, + {"rate": 1.35, "start": 55800000}, + }, + } + datum["carbRatios"] = map[string]interface{}{ + "Simple": []map[string]interface{}{ + {"amount": 10, "start": 0}, + {"amount": 10, "start": 46800000}, + }, + "Standard": []map[string]interface{}{ + {"amount": 10, "start": 0}, + {"amount": 10, "start": 46800000}, + }, + } + datum["insulinSensitivities"] = map[string]interface{}{ + "Simple": []map[string]interface{}{ + {"amount": 2.7753739955227665, "start": 0}, + {"amount": 2.7753739955227665, "start": 46800000}, + }, + "Standard": []map[string]interface{}{ + {"amount": 2.7753739955227665, "start": 0}, + {"amount": 2.7753739955227665, "start": 46800000}, + }, + } + + datum["bgTargets"] = map[string]interface{}{ + "Simple": []map[string]interface{}{ + {"target": 5.550747991045533, "start": 0}, + {"target": 5.550747991045533, "start": 46800000}, + }, + "Standard": []map[string]interface{}{ + {"target": 5.550747991045533, "start": 0}, + {"target": 5.550747991045533, "start": 46800000}, + }, + } + + datum["payload"] = map[string]interface{}{ + "logIndices": []interface{}{0}, + } + + return datum +} + +func carelinkPumpSettings() map[string]interface{} { + datum := base("MiniMed 530G - 751-=-11111111") + + datum["type"] = "pumpSettings" + datum["activeSchedule"] = "standard" + datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mg/dL"} + datum["basalSchedules"] = map[string]interface{}{ + "standard": []map[string]interface{}{ + {"rate": 0.5, "start": 0}, + {"rate": 1.35, "start": 55800000}, + }, + "pattern a": []map[string]interface{}{ + {"rate": 0.5, "start": 0}, + {"rate": 1.35, "start": 55800000}, + }, + "pattern b": []map[string]interface{}{}, + } + datum["carbRatio"] = []map[string]interface{}{ + {"amount": 10, "start": 0}, + {"amount": 10, "start": 32400000}, + } + datum["insulinSensitivity"] = []map[string]interface{}{ + {"amount": 2.7753739955227665, "start": 0}, + {"amount": 2.7753739955227665, "start": 46800000}, + } + + datum["bgTarget"] = []map[string]interface{}{ + {"target": 5.550747991045533, "start": 0}, + {"target": 5.550747991045533, "start": 46800000}, + } + + datum["payload"] = map[string]interface{}{ + "logIndices": []interface{}{5309}, + } + return datum +} + +func omnipodPumpSettingsDatum() map[string]interface{} { + + datum := base("InsOmn-837268") + datum["type"] = "pumpSettings" + datum["activeSchedule"] = "Mine-2016" + datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mg/dL"} + datum["basalSchedules"] = map[string]interface{}{ + "Mine-2016": []map[string]interface{}{ + {"rate": 0.5, "start": 0}, + {"rate": 1.35, "start": 55800000}, + }, + "camp 2015": []map[string]interface{}{ + {"rate": 0.5, "start": 0}, + {"rate": 1.35, "start": 55800000}, + }, + "weekend b": []map[string]interface{}{}, + } + datum["carbRatio"] = []map[string]interface{}{ + {"amount": 10, "start": 0}, + {"amount": 10, "start": 32400000}, + } + datum["insulinSensitivity"] = []map[string]interface{}{ + {"amount": 2.7753739955227665, "start": 0}, + {"amount": 2.7753739955227665, "start": 46800000}, + } + + datum["bgTarget"] = []map[string]interface{}{ + {"target": 5.550747991045533, "start": 0, "high": 7.2159723883591935}, + {"target": 5.550747991045533, "start": 46800000, "high": 7.2159723883591935}, + } + return datum +} + +var CBGDexcomG5MobDatum = dexG5MobDatum() +var PumpSettingsTandem = tandemPumpSettingsDatum() +var PumpSettingsCarelink = carelinkPumpSettings() +var PumpSettingsOmnipod = omnipodPumpSettingsDatum() diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 6fc9162335..617161bb79 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -92,6 +92,10 @@ func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { return datumID, nil, errors.New("cannot get the datum type") } + //remove as uneeded and can cause issues if invalid type + delete(bsonData, "payload") + delete(bsonData, "annotations") + switch datumType { case basal.Type: var datum *basal.Basal diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index f67385906e..8ff623fe49 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -14,6 +14,7 @@ import ( "github.com/tidepool-org/platform/data/types/settings/pump" pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" + "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils/test" ) var _ = Describe("back-37", func() { @@ -236,6 +237,43 @@ var _ = Describe("back-37", func() { }) }) }) + Context("Historic datum", func() { + + It("g5 dexcom", func() { + actualID, actual, err := utils.GetDatumUpdates(getBSONData(test.CBGDexcomG5MobDatum)) + Expect(err).To(BeNil()) + Expect(actual).ToNot(BeNil()) + Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "TKJurm+/SuA5tarn/nATa7Nw0LXgwGel67lgJihUctM="}}}})) + Expect(actualID).ToNot(BeEmpty()) + }) + + It("carelink medtronic pumpSettings", func() { + actualID, actual, err := utils.GetDatumUpdates(getBSONData(test.PumpSettingsCarelink)) + Expect(err).To(BeNil()) + Expect(actual).ToNot(BeNil()) + + Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "NC17pw1UAaab50iChhQXJ+N9dTi6GduTy9UjsMHolow="}}}})) + Expect(actualID).ToNot(BeEmpty()) + }) + + It("tandem pumpSettings", func() { + actualID, actual, err := utils.GetDatumUpdates(getBSONData(test.PumpSettingsTandem)) + Expect(err).To(BeNil()) + Expect(actual).ToNot(BeNil()) + Expect(len(actual)).To(Equal(1)) + Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "bpKLJbi5JfqD7N0WJ1vj0ck03c9EZ3U0H09TCLhdd3k="}}}})) + Expect(actualID).ToNot(BeEmpty()) + }) + + It("omnipod pumpSettings", func() { + actualID, actual, err := utils.GetDatumUpdates(getBSONData(test.PumpSettingsOmnipod)) + Expect(err).To(BeNil()) + Expect(actual).ToNot(BeNil()) + Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "oH7/6EEgUjRTeafEpm74fVTYMBvMdQ65/rhg0oFoev8="}}}})) + Expect(actualID).ToNot(BeEmpty()) + }) + + }) }) }) }) From 9d2a7bbdf38e4afa4f93d1891c591043403248d3 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 16 Jan 2024 14:15:29 +1300 Subject: [PATCH 111/413] track number of errors --- .../20231128_jellyfish_migration/jellyfish_migration.go | 6 +++--- .../20231128_jellyfish_migration/utils/migrationUtil.go | 8 +++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 53bf10df3b..172ce81b35 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -239,9 +239,9 @@ func (m *Migration) fetchAndUpdateBatch() bool { m.migrationUtil.SetData(updateOp, datumID) } } - - log.Printf("2. data update took [%s] for [%d] items", time.Since(updateStart), m.migrationUtil.GetUpdatesCount()) - return m.migrationUtil.GetUpdatesCount() > 0 + updated, errored := m.migrationUtil.GetUpdateCounts() + log.Printf("2. data update took [%s] for [%d] items and [%d] errors", time.Since(updateStart), updated, errored) + return updated > 0 } return false } diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 3948a95ed1..12fc76924e 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -40,6 +40,7 @@ type migrationUtil struct { client *mongo.Client config *MigrationUtilConfig updates []mongo.WriteModel + errorsCount int lastUpdatedId string } @@ -49,7 +50,7 @@ type MigrationUtil interface { OnError(reportErr error, id string, msg string) SetData(update *mongo.UpdateOneModel, lastID string) GetLastID() string - GetUpdatesCount() int + GetUpdateCounts() (int, int) } // MigrationUtil helps managed the migration process @@ -119,8 +120,8 @@ func (m *migrationUtil) SetData(update *mongo.UpdateOneModel, lastID string) { m.updates = append(m.updates, update) } -func (m *migrationUtil) GetUpdatesCount() int { - return len(m.updates) +func (m *migrationUtil) GetUpdateCounts() (int, int) { + return len(m.updates), m.errorsCount } func (m *migrationUtil) GetLastID() string { @@ -185,6 +186,7 @@ func (c *MigrationUtilConfig) SetStopOnErr(stopOnErr bool) *MigrationUtilConfig func (m *migrationUtil) OnError(reportErr error, id string, msg string) { var errFormat = "[id=%s] %s %s\n" if reportErr != nil { + m.errorsCount++ f, err := os.OpenFile("error.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { From 52534abfbccec3be874cbb46f8494324be1d7385 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 19 Jan 2024 07:54:01 +1300 Subject: [PATCH 112/413] update logging and calc of counts --- .../jellyfish_migration.go | 8 +-- .../utils/migrationUtil.go | 54 +++++++++---------- .../utils/utils_test.go | 2 - 3 files changed, 31 insertions(+), 33 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 172ce81b35..780e7c074c 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -190,8 +190,8 @@ func (m *Migration) fetchAndUpdateBatch() bool { selector["_id"] = idNotObjectID } - batchSize := int32(10000) - limit := int64(50000) + batchSize := int32(5000) + limit := int64(10000) if dataC := m.getDataCollection(); dataC != nil { fetchStart := time.Now() @@ -210,7 +210,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { defer dDataCursor.Close(m.ctx) - log.Printf("1. data fetch [%v] took [%s]", selector, time.Since(fetchStart)) + log.Printf("fetch [%v] took [%s]", selector, time.Since(fetchStart)) updateStart := time.Now() @@ -240,7 +240,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { } } updated, errored := m.migrationUtil.GetUpdateCounts() - log.Printf("2. data update took [%s] for [%d] items and [%d] errors", time.Since(updateStart), updated, errored) + log.Printf("update took [%s] for [%d] items with [%d] errors", time.Since(updateStart), updated, errored) return updated > 0 } return false diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 12fc76924e..bef2d087d4 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -41,6 +41,7 @@ type migrationUtil struct { config *MigrationUtilConfig updates []mongo.WriteModel errorsCount int + updatedCount int lastUpdatedId string } @@ -69,9 +70,11 @@ func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client, lastID } m := &migrationUtil{ - client: client, - config: config, - updates: []mongo.WriteModel{}, + client: client, + config: config, + updates: []mongo.WriteModel{}, + errorsCount: 0, + updatedCount: 0, } if lastID != nil { m.lastUpdatedId = *lastID @@ -90,28 +93,17 @@ func (m *migrationUtil) Initialize(ctx context.Context, dataC *mongo.Collection) } func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func() bool) error { - totalMigrated := 0 - migrateStart := time.Now() - for fetchAndUpdateFn() { - writeStart := time.Now() - updatedCount, err := m.writeUpdates(ctx, dataC) - if err != nil { + if err := m.writeUpdates(ctx, dataC); err != nil { log.Printf("failed writing batch: %s", err) return err } - log.Printf("4. data write took [%s] for [%d] items", time.Since(writeStart), updatedCount) - totalMigrated = totalMigrated + updatedCount if m.config.cap != nil { - if totalMigrated >= *m.config.cap { + if m.updatedCount >= *m.config.cap { break } } } - log.Printf("migration took [%s] for [%d] items ", time.Since(migrateStart), totalMigrated) - if m.config.dryRun { - log.Println("dry-run so no changes applied") - } return nil } @@ -121,7 +113,7 @@ func (m *migrationUtil) SetData(update *mongo.UpdateOneModel, lastID string) { } func (m *migrationUtil) GetUpdateCounts() (int, int) { - return len(m.updates), m.errorsCount + return m.updatedCount, m.errorsCount } func (m *migrationUtil) GetLastID() string { @@ -367,13 +359,14 @@ func (m *migrationUtil) blockUntilDBReady(ctx context.Context) error { return nil } -func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collection) (int, error) { +func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collection) error { if dataC == nil { - return 0, errors.New("missing required collection to write updates to") + return errors.New("missing required collection to write updates to") } if len(m.updates) == 0 { - return 0, nil + return nil } + var getBatches = func(chunkSize int) [][]mongo.WriteModel { batches := [][]mongo.WriteModel{} for i := 0; i < len(m.updates); i += chunkSize { @@ -385,27 +378,34 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio } return batches } - updateCount := 0 + writtenCount := 0 + writeStart := time.Now() for _, batch := range getBatches(int(*m.writeBatchSize)) { if err := m.blockUntilDBReady(ctx); err != nil { - return updateCount, err + return err } if err := m.checkFreeSpace(ctx, dataC); err != nil { - return updateCount, err + return err } if m.config.dryRun { - updateCount += len(batch) + writtenCount += len(batch) continue } results, err := dataC.BulkWrite(ctx, batch) if err != nil { log.Printf("error writing batch updates %v", err) - return updateCount, err + return err } - updateCount += int(results.ModifiedCount) + writtenCount += int(results.ModifiedCount) writeLastItemUpdate(m.lastUpdatedId, m.config.dryRun) } - return updateCount, nil + m.updates = []mongo.WriteModel{} + m.updatedCount = m.updatedCount + writtenCount + log.Printf("bulk write took [%s] for [%d] items for a total of [%d]", time.Since(writeStart), m.updatedCount, writtenCount) + if m.config.dryRun { + log.Println("dry-run so no changes applied") + } + return nil } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 8ff623fe49..0860577823 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -238,7 +238,6 @@ var _ = Describe("back-37", func() { }) }) Context("Historic datum", func() { - It("g5 dexcom", func() { actualID, actual, err := utils.GetDatumUpdates(getBSONData(test.CBGDexcomG5MobDatum)) Expect(err).To(BeNil()) @@ -251,7 +250,6 @@ var _ = Describe("back-37", func() { actualID, actual, err := utils.GetDatumUpdates(getBSONData(test.PumpSettingsCarelink)) Expect(err).To(BeNil()) Expect(actual).ToNot(BeNil()) - Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "NC17pw1UAaab50iChhQXJ+N9dTi6GduTy9UjsMHolow="}}}})) Expect(actualID).ToNot(BeEmpty()) }) From 28c5c9d9e8afcbe3e9b24f016cb3fae126aa2c1e Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 19 Jan 2024 09:05:05 +1300 Subject: [PATCH 113/413] allow config of batch and limit --- .../jellyfish_migration.go | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 780e7c074c..bbc3650d1f 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -25,13 +25,15 @@ type Migration struct { } type config struct { - cap int - uri string - dryRun bool - stopOnErr bool - userID string - lastUpdatedId string - nopPercent int + cap int + uri string + dryRun bool + stopOnErr bool + userID string + lastUpdatedId string + nopPercent int + queryBatchSize int64 + queryLimit int64 } const DryRunFlag = "dry-run" @@ -151,6 +153,20 @@ func (m *Migration) Initialize() error { Destination: &m.config.userID, Required: false, }, + cli.Int64Flag{ + Name: "query-limit", + Usage: "max number of items to return", + Destination: &m.config.queryLimit, + Value: 50000, + Required: false, + }, + cli.Int64Flag{ + Name: "query-batch", + Usage: "max number of items in each query batch", + Destination: &m.config.queryBatchSize, + Value: 10000, + Required: false, + }, ) return nil } @@ -190,8 +206,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { selector["_id"] = idNotObjectID } - batchSize := int32(5000) - limit := int64(10000) + batchSize := int32(m.config.queryBatchSize) if dataC := m.getDataCollection(); dataC != nil { fetchStart := time.Now() @@ -200,7 +215,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { &options.FindOptions{ Sort: bson.M{"_id": 1}, BatchSize: &batchSize, - Limit: &limit, + Limit: &m.config.queryLimit, }, ) if err != nil { From 58641036a990d6ce46c6b92b6babb01652354eb1 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 19 Jan 2024 09:44:44 +1300 Subject: [PATCH 114/413] fix counts --- .../20231128_jellyfish_migration/jellyfish_migration.go | 2 +- .../20231128_jellyfish_migration/utils/migrationUtil.go | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index bbc3650d1f..282ea543ca 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -254,7 +254,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { m.migrationUtil.SetData(updateOp, datumID) } } - updated, errored := m.migrationUtil.GetUpdateCounts() + updated, _, errored := m.migrationUtil.GetCounts() log.Printf("update took [%s] for [%d] items with [%d] errors", time.Since(updateStart), updated, errored) return updated > 0 } diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index bef2d087d4..85d8c7475f 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -51,7 +51,7 @@ type MigrationUtil interface { OnError(reportErr error, id string, msg string) SetData(update *mongo.UpdateOneModel, lastID string) GetLastID() string - GetUpdateCounts() (int, int) + GetCounts() (int, int, int) } // MigrationUtil helps managed the migration process @@ -112,8 +112,10 @@ func (m *migrationUtil) SetData(update *mongo.UpdateOneModel, lastID string) { m.updates = append(m.updates, update) } -func (m *migrationUtil) GetUpdateCounts() (int, int) { - return m.updatedCount, m.errorsCount +// GetCounts +// updates, migrated, errored +func (m *migrationUtil) GetCounts() (int, int, int) { + return len(m.updates), m.updatedCount, m.errorsCount } func (m *migrationUtil) GetLastID() string { From efc382fa9455acf0bee137c11028df3e47609b53 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 19 Jan 2024 11:42:16 +1300 Subject: [PATCH 115/413] stats --- .../jellyfish_migration.go | 6 ++-- .../utils/migrationUtil.go | 29 +++++++++++++++---- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 282ea543ca..6db793abb1 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -254,9 +254,9 @@ func (m *Migration) fetchAndUpdateBatch() bool { m.migrationUtil.SetData(updateOp, datumID) } } - updated, _, errored := m.migrationUtil.GetCounts() - log.Printf("update took [%s] for [%d] items with [%d] errors", time.Since(updateStart), updated, errored) - return updated > 0 + stats := m.migrationUtil.GetStats() + log.Printf("update took [%s] for [%d] items with [%d] errors", time.Since(updateStart), stats.ToApply, stats.Errored) + return stats.ToApply > 0 } return false } diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 85d8c7475f..2a22c583e1 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -43,6 +43,14 @@ type migrationUtil struct { errorsCount int updatedCount int lastUpdatedId string + startedAt time.Time +} + +type MigrationStats struct { + Errored int + Applied int + ToApply int + Elapsed time.Duration } type MigrationUtil interface { @@ -51,7 +59,7 @@ type MigrationUtil interface { OnError(reportErr error, id string, msg string) SetData(update *mongo.UpdateOneModel, lastID string) GetLastID() string - GetCounts() (int, int, int) + GetStats() MigrationStats } // MigrationUtil helps managed the migration process @@ -75,6 +83,7 @@ func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client, lastID updates: []mongo.WriteModel{}, errorsCount: 0, updatedCount: 0, + startedAt: time.Now(), } if lastID != nil { m.lastUpdatedId = *lastID @@ -104,6 +113,7 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe } } } + m.GetStats().report() return nil } @@ -112,10 +122,17 @@ func (m *migrationUtil) SetData(update *mongo.UpdateOneModel, lastID string) { m.updates = append(m.updates, update) } -// GetCounts -// updates, migrated, errored -func (m *migrationUtil) GetCounts() (int, int, int) { - return len(m.updates), m.updatedCount, m.errorsCount +func (m *migrationUtil) GetStats() MigrationStats { + return MigrationStats{ + Errored: m.errorsCount, + ToApply: len(m.updates), + Applied: m.updatedCount, + Elapsed: time.Since(m.startedAt), + } +} + +func (c MigrationStats) report() { + log.Printf("migrated [%d] items with [%d] errors and an elapsed time of [%s]\n", c.Applied, c.Errored, c.Elapsed) } func (m *migrationUtil) GetLastID() string { @@ -405,7 +422,7 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio } m.updates = []mongo.WriteModel{} m.updatedCount = m.updatedCount + writtenCount - log.Printf("bulk write took [%s] for [%d] items for a total of [%d]", time.Since(writeStart), m.updatedCount, writtenCount) + log.Printf("bulk write took [%s] for [%d] items\n", time.Since(writeStart), writtenCount) if m.config.dryRun { log.Println("dry-run so no changes applied") } From 71778df14cf3447c1becd5794c5b748fbfdaa925 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 19 Jan 2024 12:35:52 +1300 Subject: [PATCH 116/413] stats update --- .../20231128_jellyfish_migration/jellyfish_migration.go | 2 +- .../20231128_jellyfish_migration/utils/migrationUtil.go | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 6db793abb1..51b274fc33 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -225,7 +225,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { defer dDataCursor.Close(m.ctx) - log.Printf("fetch [%v] took [%s]", selector, time.Since(fetchStart)) + log.Printf("fetch took [%v] with query [%s] ", time.Since(fetchStart), selector) updateStart := time.Now() diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 2a22c583e1..8d001cb008 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -127,7 +127,7 @@ func (m *migrationUtil) GetStats() MigrationStats { Errored: m.errorsCount, ToApply: len(m.updates), Applied: m.updatedCount, - Elapsed: time.Since(m.startedAt), + Elapsed: time.Since(m.startedAt).Truncate(time.Millisecond), } } @@ -422,9 +422,10 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio } m.updates = []mongo.WriteModel{} m.updatedCount = m.updatedCount + writtenCount - log.Printf("bulk write took [%s] for [%d] items\n", time.Since(writeStart), writtenCount) if m.config.dryRun { log.Println("dry-run so no changes applied") + } else { + log.Printf("write took [%s] for [%d] items\n", time.Since(writeStart), writtenCount) } return nil } From 7276bbbb97a1db5d52f10608707637d7ed8650ae Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 19 Jan 2024 12:56:39 +1300 Subject: [PATCH 117/413] less debug for longer runs --- .../20231128_jellyfish_migration/jellyfish_migration.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 51b274fc33..0e7ead2907 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -209,7 +209,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { batchSize := int32(m.config.queryBatchSize) if dataC := m.getDataCollection(); dataC != nil { - fetchStart := time.Now() + //fetchStart := time.Now() dDataCursor, err := dataC.Find(m.ctx, selector, &options.FindOptions{ @@ -225,7 +225,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { defer dDataCursor.Close(m.ctx) - log.Printf("fetch took [%v] with query [%s] ", time.Since(fetchStart), selector) + //log.Printf("fetch took [%v] with query [%s] ", time.Since(fetchStart), selector) updateStart := time.Now() @@ -255,7 +255,9 @@ func (m *Migration) fetchAndUpdateBatch() bool { } } stats := m.migrationUtil.GetStats() - log.Printf("update took [%s] for [%d] items with [%d] errors", time.Since(updateStart), stats.ToApply, stats.Errored) + if stats.Errored > 0 { + log.Printf("update took [%s] for [%d] items with [%d] errors", time.Since(updateStart), stats.ToApply, stats.Errored) + } return stats.ToApply > 0 } return false From b54af12810f312fe4ac9cd80313ccfc6a8af9ec6 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 19 Jan 2024 13:44:32 +1300 Subject: [PATCH 118/413] stats format --- migrations/20231128_jellyfish_migration/utils/migrationUtil.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 8d001cb008..f0425e02c3 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -132,7 +132,7 @@ func (m *migrationUtil) GetStats() MigrationStats { } func (c MigrationStats) report() { - log.Printf("migrated [%d] items with [%d] errors and an elapsed time of [%s]\n", c.Applied, c.Errored, c.Elapsed) + log.Printf("elapsed [%s] for [%d] items migrated with [%d] errors\n", c.Elapsed, c.Applied, c.Errored) } func (m *migrationUtil) GetLastID() string { @@ -426,6 +426,7 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio log.Println("dry-run so no changes applied") } else { log.Printf("write took [%s] for [%d] items\n", time.Since(writeStart), writtenCount) + m.GetStats().report() } return nil } From b386dcd09c1153733a05ca1989781a212e8f0bd5 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 19 Jan 2024 15:08:29 +1300 Subject: [PATCH 119/413] allow audit --- .../jellyfish_migration.go | 35 ++++++++++++++----- .../utils/migrationUtil.go | 12 +++++++ 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 0e7ead2907..a46da5813a 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -28,6 +28,7 @@ type config struct { cap int uri string dryRun bool + audit bool stopOnErr bool userID string lastUpdatedId string @@ -49,9 +50,11 @@ func main() { func NewMigration(ctx context.Context) *Migration { return &Migration{ - config: &config{}, - ctx: ctx, - cli: cli.NewApp(), + config: &config{ + audit: false, + }, + ctx: ctx, + cli: cli.NewApp(), } } @@ -83,7 +86,9 @@ func (m *Migration) RunAndExit() { log.Printf("prepare failed: %s", err) return err } - if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndUpdateBatch); err != nil { + if m.config.audit { + m.audit() + } else if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndUpdateBatch); err != nil { log.Printf("execute failed: %s", err) return err } @@ -118,6 +123,11 @@ func (m *Migration) Initialize() error { Usage: "stop migration on error", Destination: &m.config.stopOnErr, }, + cli.BoolFlag{ + Name: "audit", + Usage: "run audit", + Destination: &m.config.audit, + }, cli.IntFlag{ Name: "cap", Usage: "max number of records migrate", @@ -209,7 +219,6 @@ func (m *Migration) fetchAndUpdateBatch() bool { batchSize := int32(m.config.queryBatchSize) if dataC := m.getDataCollection(); dataC != nil { - //fetchStart := time.Now() dDataCursor, err := dataC.Find(m.ctx, selector, &options.FindOptions{ @@ -222,11 +231,8 @@ func (m *Migration) fetchAndUpdateBatch() bool { log.Printf("failed to select data: %s", err) return false } - defer dDataCursor.Close(m.ctx) - //log.Printf("fetch took [%v] with query [%s] ", time.Since(fetchStart), selector) - updateStart := time.Now() for dDataCursor.Next(m.ctx) { @@ -262,3 +268,16 @@ func (m *Migration) fetchAndUpdateBatch() bool { } return false } + +func (m *Migration) audit() { + m.migrationUtil.Audit(m.ctx, m.getDataCollection(), map[string]interface{}{ + "to migrate": bson.M{ + "_deduplicator": bson.M{"$exists": false}, + "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, + }, + "migrated": bson.M{ + "_deduplicator": bson.M{"$exists": true}, + "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, + }, + }) +} diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index f0425e02c3..0e0893aae2 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -60,6 +60,7 @@ type MigrationUtil interface { SetData(update *mongo.UpdateOneModel, lastID string) GetLastID() string GetStats() MigrationStats + Audit(ctx context.Context, dataC *mongo.Collection, queries map[string]interface{}) } // MigrationUtil helps managed the migration process @@ -430,3 +431,14 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio } return nil } + +func (m *migrationUtil) Audit(ctx context.Context, dataC *mongo.Collection, queries map[string]interface{}) { + for context, query := range queries { + count, err := dataC.CountDocuments(ctx, query) + if err != nil { + log.Printf("failed to run audit query: %s", err) + return + } + log.Printf("%s returns [%d] items", context, count) + } +} From c829baf7c860d9b54ba9ebc1074e6eaecccedfca Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 19 Jan 2024 16:05:46 +1300 Subject: [PATCH 120/413] audit too slow --- .../20231128_jellyfish_migration/jellyfish_migration.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index a46da5813a..8c0c763b44 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -86,9 +86,8 @@ func (m *Migration) RunAndExit() { log.Printf("prepare failed: %s", err) return err } - if m.config.audit { - m.audit() - } else if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndUpdateBatch); err != nil { + + if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndUpdateBatch); err != nil { log.Printf("execute failed: %s", err) return err } From 19a718d47d69fd9c468fcbf6259c22feeca98e45 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 23 Jan 2024 10:44:25 +1300 Subject: [PATCH 121/413] update audit queries --- .../jellyfish_migration.go | 43 ++++++++++++++++--- .../utils/migrationUtil.go | 8 ++-- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 8c0c763b44..6fef735bc7 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -87,6 +87,11 @@ func (m *Migration) RunAndExit() { return err } + if m.config.audit { + log.Println("running audit ...") + return m.audit() + } + if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndUpdateBatch); err != nil { log.Printf("execute failed: %s", err) return err @@ -268,15 +273,39 @@ func (m *Migration) fetchAndUpdateBatch() bool { return false } -func (m *Migration) audit() { - m.migrationUtil.Audit(m.ctx, m.getDataCollection(), map[string]interface{}{ - "to migrate": bson.M{ - "_deduplicator": bson.M{"$exists": false}, - "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, - }, - "migrated": bson.M{ +func (m *Migration) audit() error { + return m.migrationUtil.Audit(m.ctx, m.getDataCollection(), map[string]interface{}{ + "pumpSettings_boluses": bson.M{ "_deduplicator": bson.M{"$exists": true}, "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, + "type": "pumpSettings", + "bolus": bson.M{"$exists": false}, + "boluses": bson.M{"$exists": true}, + }, + "pumpSettings_sleepSchedules": bson.M{ + "_deduplicator": bson.M{"$exists": true}, + "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, + "type": "pumpSettings", + "sleepSchedules": bson.M{"$exists": true}, }, + // "smbg_value": bson.M{ + // "_deduplicator": bson.M{"$exists": true}, + // "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, + // "type": selfmonitored.Type, + // "units": bson.M{"$not": bson.M{"$in": []string{glucose.MgdL, glucose.Mgdl}}}, + // }, + // "cbg_value": bson.M{ + // "_deduplicator": bson.M{"$exists": true}, + // "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, + // "type": continuous.Type, + // "units": bson.M{"$not": bson.M{"$in": []string{glucose.MgdL, glucose.Mgdl}}}, + // }, + // "ketone_value": bson.M{ + // "_deduplicator": bson.M{"$exists": true}, + // "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, + // "type": ketone.Type, + // "units": bson.M{"$not": bson.M{"$in": []string{glucose.MgdL, glucose.Mgdl}}}, + // "$where": "this.value.length > ", + // }, }) } diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 0e0893aae2..3ea2eae758 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -60,7 +60,7 @@ type MigrationUtil interface { SetData(update *mongo.UpdateOneModel, lastID string) GetLastID() string GetStats() MigrationStats - Audit(ctx context.Context, dataC *mongo.Collection, queries map[string]interface{}) + Audit(ctx context.Context, dataC *mongo.Collection, queries map[string]interface{}) error } // MigrationUtil helps managed the migration process @@ -432,13 +432,15 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio return nil } -func (m *migrationUtil) Audit(ctx context.Context, dataC *mongo.Collection, queries map[string]interface{}) { +func (m *migrationUtil) Audit(ctx context.Context, dataC *mongo.Collection, queries map[string]interface{}) error { for context, query := range queries { + log.Printf("audit %v", query) count, err := dataC.CountDocuments(ctx, query) if err != nil { log.Printf("failed to run audit query: %s", err) - return + return err } log.Printf("%s returns [%d] items", context, count) } + return nil } From b13ab2697b4fa16a9b7d3743cbcf73bf8d171aa5 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 24 Jan 2024 15:42:19 +1300 Subject: [PATCH 122/413] simple readme - remove bogus audit - remove GetBGValuePlatformPrecision and use datum normalise instead - if normalised then persist the changes --- .../jellyfish_migration.go | 56 +------------ .../20231128_jellyfish_migration/readme.md | 34 ++++++++ .../utils/migrationUtil.go | 14 ---- .../utils/utils.go | 62 +++++++------- .../utils/utils_test.go | 81 ++++++++++++++++--- 5 files changed, 140 insertions(+), 107 deletions(-) create mode 100644 migrations/20231128_jellyfish_migration/readme.md diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 6fef735bc7..56e3e1f81a 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -28,7 +28,6 @@ type config struct { cap int uri string dryRun bool - audit bool stopOnErr bool userID string lastUpdatedId string @@ -50,11 +49,9 @@ func main() { func NewMigration(ctx context.Context) *Migration { return &Migration{ - config: &config{ - audit: false, - }, - ctx: ctx, - cli: cli.NewApp(), + config: &config{}, + ctx: ctx, + cli: cli.NewApp(), } } @@ -87,11 +84,6 @@ func (m *Migration) RunAndExit() { return err } - if m.config.audit { - log.Println("running audit ...") - return m.audit() - } - if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndUpdateBatch); err != nil { log.Printf("execute failed: %s", err) return err @@ -127,11 +119,6 @@ func (m *Migration) Initialize() error { Usage: "stop migration on error", Destination: &m.config.stopOnErr, }, - cli.BoolFlag{ - Name: "audit", - Usage: "run audit", - Destination: &m.config.audit, - }, cli.IntFlag{ Name: "cap", Usage: "max number of records migrate", @@ -272,40 +259,3 @@ func (m *Migration) fetchAndUpdateBatch() bool { } return false } - -func (m *Migration) audit() error { - return m.migrationUtil.Audit(m.ctx, m.getDataCollection(), map[string]interface{}{ - "pumpSettings_boluses": bson.M{ - "_deduplicator": bson.M{"$exists": true}, - "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, - "type": "pumpSettings", - "bolus": bson.M{"$exists": false}, - "boluses": bson.M{"$exists": true}, - }, - "pumpSettings_sleepSchedules": bson.M{ - "_deduplicator": bson.M{"$exists": true}, - "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, - "type": "pumpSettings", - "sleepSchedules": bson.M{"$exists": true}, - }, - // "smbg_value": bson.M{ - // "_deduplicator": bson.M{"$exists": true}, - // "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, - // "type": selfmonitored.Type, - // "units": bson.M{"$not": bson.M{"$in": []string{glucose.MgdL, glucose.Mgdl}}}, - // }, - // "cbg_value": bson.M{ - // "_deduplicator": bson.M{"$exists": true}, - // "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, - // "type": continuous.Type, - // "units": bson.M{"$not": bson.M{"$in": []string{glucose.MgdL, glucose.Mgdl}}}, - // }, - // "ketone_value": bson.M{ - // "_deduplicator": bson.M{"$exists": true}, - // "_id": bson.M{"$not": bson.M{"$type": "objectId"}}, - // "type": ketone.Type, - // "units": bson.M{"$not": bson.M{"$in": []string{glucose.MgdL, glucose.Mgdl}}}, - // "$where": "this.value.length > ", - // }, - }) -} diff --git a/migrations/20231128_jellyfish_migration/readme.md b/migrations/20231128_jellyfish_migration/readme.md new file mode 100644 index 0000000000..e39f5ced17 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/readme.md @@ -0,0 +1,34 @@ +# Running jellyfish migration tool + +## login to server with mongo access + +## clone platform repo + +## set `uri` for migration too +- go to `platform/cd migrations/20231128_jellyfish_migration/` +- create file `uri` +- add single line to file with mongo connection string `mongodb+srv:///?retryWrites=true&w=majority` + +## run tool +- help: +``` +GLOBAL OPTIONS: + --dry-run, -n dry run only; do not migrate + --stop-error stop migration on error + --audit run audit + --cap value max number of records migrate (default: 0) + --nop-percent value how much of the oplog is NOP (default: 50) + --uri value mongo connection URI [./uri] + --datum-id value id of last datum updated [./lastUpdatedId] + --user-id value id of single user to migrate + --query-limit value max number of items to return (default: 50000) + --query-batch value max number of items in each query batch (default: 10000) + --help, -h show help + +``` +- test migration for a user: + `go run jellyfish_migration.go --stop-error --dry-run --user-id=924edd2e-b8fc-45ad-b3f4-3032bb6b0a45` + +- run migration: + `go run jellyfish_migration.go --user-id=924edd2e-b8fc-45ad-b3f4-3032bb6b0a45` + diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 3ea2eae758..f0425e02c3 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -60,7 +60,6 @@ type MigrationUtil interface { SetData(update *mongo.UpdateOneModel, lastID string) GetLastID() string GetStats() MigrationStats - Audit(ctx context.Context, dataC *mongo.Collection, queries map[string]interface{}) error } // MigrationUtil helps managed the migration process @@ -431,16 +430,3 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio } return nil } - -func (m *migrationUtil) Audit(ctx context.Context, dataC *mongo.Collection, queries map[string]interface{}) error { - for context, query := range queries { - log.Printf("audit %v", query) - count, err := dataC.CountDocuments(ctx, query) - if err != nil { - log.Printf("failed to run audit query: %s", err) - return err - } - log.Printf("%s returns [%d] items", context, count) - } - return nil -} diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 617161bb79..e6218760ab 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -2,14 +2,12 @@ package utils import ( "encoding/json" - "fmt" "log" "slices" "strings" "go.mongodb.org/mongo-driver/bson" - "github.com/tidepool-org/platform/data/blood/glucose" "github.com/tidepool-org/platform/data/deduplicator/deduplicator" "github.com/tidepool-org/platform/data/normalizer" "github.com/tidepool-org/platform/data/types" @@ -67,15 +65,6 @@ func pumpSettingsHasBolus(bsonData bson.M) bool { return false } -func GetBGValuePlatformPrecision(mmolVal float64) float64 { - if len(fmt.Sprintf("%v", mmolVal)) > 7 { - mgdlVal := mmolVal * glucose.MmolLToMgdLConversionFactor - mgdL := glucose.MgdL - mmolVal = *glucose.NormalizeValueForUnits(&mgdlVal, &mgdL) - } - return mmolVal -} - func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { updates := []bson.M{} set := bson.M{} @@ -92,7 +81,8 @@ func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { return datumID, nil, errors.New("cannot get the datum type") } - //remove as uneeded and can cause issues if invalid type + // TODO: based on discussions we want to ensure that these are the correct type + // even though we are not using them for the hash generation delete(bsonData, "payload") delete(bsonData, "annotations") @@ -174,11 +164,16 @@ func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { if err != nil { return datumID, nil, err } - if *datum.Units != glucose.MgdL && *datum.Units != glucose.Mgdl { - // NOTE: we need to ensure the same precision for the - // converted value as it is used to calculate the hash - val := GetBGValuePlatformPrecision(*datum.Value) - datum.Value = &val + beforeVal := datum.Value + beforeUnits := datum.Units + datum.Normalize(normalizer.New()) + afterVal := datum.Value + afterUnits := datum.Units + if *beforeVal != *afterVal { + set["value"] = afterVal + } + if *beforeUnits != *afterUnits { + set["units"] = afterUnits } identityFields, err = datum.IdentityFields() if err != nil { @@ -194,11 +189,16 @@ func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { if err != nil { return datumID, nil, err } - if *datum.Units != glucose.MgdL && *datum.Units != glucose.Mgdl { - // NOTE: we need to ensure the same precision for the - // converted value as it is used to calculate the hash - val := GetBGValuePlatformPrecision(*datum.Value) - datum.Value = &val + beforeVal := datum.Value + beforeUnits := datum.Units + datum.Normalize(normalizer.New()) + afterVal := datum.Value + afterUnits := datum.Units + if *beforeVal != *afterVal { + set["value"] = afterVal + } + if *beforeUnits != *afterUnits { + set["units"] = afterUnits } identityFields, err = datum.IdentityFields() if err != nil { @@ -214,11 +214,19 @@ func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { if err != nil { return datumID, nil, err } - if *datum.Units != glucose.MgdL && *datum.Units != glucose.Mgdl { - // NOTE: we need to ensure the same precision for the - // converted value as it is used to calculate the hash - val := GetBGValuePlatformPrecision(*datum.Value) - datum.Value = &val + // NOTE: applies to any type that has a `Glucose` property + // we need to normalise so that we can get the correct `Units`` and `Value`` precsion that we would if ingested via the platform. + // as these are both being used in the hash calc via the IdentityFields we want to persist these changes if they are infact updated. + beforeVal := datum.Value + beforeUnits := datum.Units + datum.Normalize(normalizer.New()) + afterVal := datum.Value + afterUnits := datum.Units + if *beforeVal != *afterVal { + set["value"] = afterVal + } + if *beforeUnits != *afterUnits { + set["units"] = afterUnits } identityFields, err = datum.IdentityFields() if err != nil { diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 0860577823..2b5eab8293 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -8,30 +8,21 @@ import ( . "github.com/onsi/gomega" "go.mongodb.org/mongo-driver/bson" + "github.com/tidepool-org/platform/data/blood/glucose" "github.com/tidepool-org/platform/data/normalizer" + "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" + glucoseTest "github.com/tidepool-org/platform/data/types/blood/glucose/test" bolusTest "github.com/tidepool-org/platform/data/types/bolus/test" "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/data/types/settings/pump" pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils/test" + "github.com/tidepool-org/platform/pointer" ) var _ = Describe("back-37", func() { var _ = Describe("utils", func() { - Context("GetBGValuePlatformPrecision", func() { - DescribeTable("return the expected mmol/L value", - func(jellyfishVal float64, expectedVal float64) { - actual := utils.GetBGValuePlatformPrecision(jellyfishVal) - Expect(actual).To(Equal(expectedVal)) - }, - Entry("original mmol/L value", 10.1, 10.1), - Entry("converted mgd/L of 100", 5.550747991045533, 5.55075), - Entry("converted mgd/L of 150", 8.3261219865683, 8.32612), - Entry("converted mgd/L of 65", 3.6079861941795968, 3.60799), - ) - }) - var _ = Describe("GetDatumUpdates", func() { var existingBolusDatum bson.M const expectedID = "some-id" @@ -237,6 +228,70 @@ var _ = Describe("back-37", func() { }) }) }) + Context("datum with glucose", func() { + + var newContinuous = func(units *string) *continuous.Continuous { + datum := continuous.New() + datum.Glucose = *glucoseTest.NewGlucose(units) + datum.Type = "cbg" + *datum.ID = expectedID + *datum.UserID = "some-user-id" + *datum.DeviceID = "some-device-id" + theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") + *datum.Time = theTime + return datum + } + + DescribeTable("should", + func(getInput func() bson.M, expected []bson.M, expectError bool) { + input := getInput() + _, actual, err := utils.GetDatumUpdates(input) + if expectError { + Expect(err).ToNot(BeNil()) + Expect(actual).To(BeNil()) + return + } + Expect(err).To(BeNil()) + if expected != nil { + Expect(actual).To(BeEquivalentTo(expected)) + } else { + Expect(actual).To(BeNil()) + } + }, + + Entry("do nothing when not normailzed", + func() bson.M { + mmolL := glucose.MmolL + cbg := newContinuous(&mmolL) + cbgData := getBSONData(cbg) + cbgData["_id"] = expectedID + cbgData["value"] = 9.5 + return cbgData + }, + []bson.M{{"$set": bson.M{ + "_deduplicator": bson.M{"hash": "lLCOZJMLvNaBx7dMc31bbX4zwSfPvxcUd0Z1uU/YIAs="}, + }}}, + false, + ), + Entry("update value when normailzed", + func() bson.M { + mgdL := glucose.MgdL + cbg := newContinuous(&mgdL) + cbgData := getBSONData(cbg) + cbgData["_id"] = expectedID + cbgData["value"] = 180 + + return cbgData + }, + []bson.M{{"$set": bson.M{ + "_deduplicator": bson.M{"hash": "FZtVRkliues5vAt25ZK+WDAqa4Q6tAAe9h2PdKM15Q4="}, + "value": pointer.FromFloat64(9.99135), + "units": pointer.FromString(glucose.MmolL), + }}}, + false, + ), + ) + }) Context("Historic datum", func() { It("g5 dexcom", func() { actualID, actual, err := utils.GetDatumUpdates(getBSONData(test.CBGDexcomG5MobDatum)) From 3d3131608fbdbd58187784ffb1c4d3563f74a8fa Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 24 Jan 2024 15:42:50 +1300 Subject: [PATCH 123/413] order --- migrations/20231128_jellyfish_migration/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/readme.md b/migrations/20231128_jellyfish_migration/readme.md index e39f5ced17..324823af16 100644 --- a/migrations/20231128_jellyfish_migration/readme.md +++ b/migrations/20231128_jellyfish_migration/readme.md @@ -27,7 +27,7 @@ GLOBAL OPTIONS: ``` - test migration for a user: - `go run jellyfish_migration.go --stop-error --dry-run --user-id=924edd2e-b8fc-45ad-b3f4-3032bb6b0a45` + `go run jellyfish_migration.go --user-id=924edd2e-b8fc-45ad-b3f4-3032bb6b0a45 --stop-error --dry-run` - run migration: `go run jellyfish_migration.go --user-id=924edd2e-b8fc-45ad-b3f4-3032bb6b0a45` From a7c309a16c626f54bca2d68a5e2375f863f13794 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 25 Jan 2024 14:24:48 +1300 Subject: [PATCH 124/413] process raw as platform datum to find issues --- .../jellyfish_migration.go | 80 ++++++++++++++++--- .../utils/migrationUtil.go | 21 ++++- .../utils/utils.go | 68 ++++++++++++++++ 3 files changed, 157 insertions(+), 12 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 56e3e1f81a..43b6c0247c 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -28,6 +28,7 @@ type config struct { cap int uri string dryRun bool + audit bool stopOnErr bool userID string lastUpdatedId string @@ -84,9 +85,17 @@ func (m *Migration) RunAndExit() { return err } - if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndUpdateBatch); err != nil { - log.Printf("execute failed: %s", err) - return err + if m.config.audit { + log.Println("auditing") + if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndProcess); err != nil { + log.Printf("audit failed: %s", err) + return err + } + } else { + if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndUpdateBatch); err != nil { + log.Printf("execute failed: %s", err) + return err + } } return nil } @@ -119,6 +128,11 @@ func (m *Migration) Initialize() error { Usage: "stop migration on error", Destination: &m.config.stopOnErr, }, + cli.BoolFlag{ + Name: "audit", + Usage: "audit data", + Destination: &m.config.audit, + }, cli.IntFlag{ Name: "cap", Usage: "max number of records migrate", @@ -180,10 +194,6 @@ func (m *Migration) getDataCollection() *mongo.Collection { return m.client.Database("data").Collection("deviceData") } -func (m *Migration) onError(errToReport error, id string, msg string) { - m.migrationUtil.OnError(errToReport, id, msg) -} - func (m *Migration) fetchAndUpdateBatch() bool { selector := bson.M{ @@ -236,7 +246,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { datumID, datumUpdates, err := utils.GetDatumUpdates(item) if err != nil { - m.onError(err, datumID, "failed getting updates") + m.migrationUtil.OnError(err, datumID, "failed applying updates") continue } for _, update := range datumUpdates { @@ -248,7 +258,7 @@ func (m *Migration) fetchAndUpdateBatch() bool { updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": item["modifiedTime"]}) } updateOp.SetUpdate(update) - m.migrationUtil.SetData(updateOp, datumID) + m.migrationUtil.SetUpdates(datumID, updateOp) } } stats := m.migrationUtil.GetStats() @@ -259,3 +269,55 @@ func (m *Migration) fetchAndUpdateBatch() bool { } return false } + +func (m *Migration) fetchAndProcess() bool { + + selector := bson.M{} + + if strings.TrimSpace(m.config.userID) != "" { + log.Printf("fetching for user %s", m.config.userID) + selector["_userId"] = m.config.userID + } + + // jellyfish uses a generated _id that is not an mongo objectId + idNotObjectID := bson.M{"$not": bson.M{"$type": "objectId"}} + + if lastID := m.migrationUtil.GetLastID(); lastID != "" { + selector["$and"] = []interface{}{ + bson.M{"_id": bson.M{"$gt": lastID}}, + bson.M{"_id": idNotObjectID}, + } + } else { + selector["_id"] = idNotObjectID + } + + batchSize := int32(m.config.queryBatchSize) + + if dataC := m.getDataCollection(); dataC != nil { + + dDataCursor, err := dataC.Find(m.ctx, selector, + &options.FindOptions{ + Sort: bson.M{"_id": 1}, + BatchSize: &batchSize, + Limit: &m.config.queryLimit, + }, + ) + if err != nil { + log.Printf("failed to select data: %s", err) + return false + } + defer dDataCursor.Close(m.ctx) + + results := []interface{}{} + if err := dDataCursor.All(m.ctx, &results); err != nil { + log.Printf("error decoding data: %s", err) + return false + } + if _, err := utils.ProcessData(results); err != nil { + m.migrationUtil.OnError(err, "", "processing data") + } + m.migrationUtil.SetFetched(results) + return len(results) > 0 + } + return false +} diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index f0425e02c3..7ec5cc02b6 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -40,6 +40,7 @@ type migrationUtil struct { client *mongo.Client config *MigrationUtilConfig updates []mongo.WriteModel + rawData []interface{} errorsCount int updatedCount int lastUpdatedId string @@ -48,6 +49,7 @@ type migrationUtil struct { type MigrationStats struct { Errored int + Fetched int Applied int ToApply int Elapsed time.Duration @@ -57,7 +59,8 @@ type MigrationUtil interface { Initialize(ctx context.Context, dataC *mongo.Collection) error Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func() bool) error OnError(reportErr error, id string, msg string) - SetData(update *mongo.UpdateOneModel, lastID string) + SetUpdates(lastID string, update ...*mongo.UpdateOneModel) + SetFetched(raw ...interface{}) GetLastID() string GetStats() MigrationStats } @@ -81,6 +84,7 @@ func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client, lastID client: client, config: config, updates: []mongo.WriteModel{}, + rawData: []interface{}{}, errorsCount: 0, updatedCount: 0, startedAt: time.Now(), @@ -117,14 +121,21 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe return nil } -func (m *migrationUtil) SetData(update *mongo.UpdateOneModel, lastID string) { +func (m *migrationUtil) SetUpdates(lastID string, update ...*mongo.UpdateOneModel) { m.lastUpdatedId = lastID - m.updates = append(m.updates, update) + for _, u := range update { + m.updates = append(m.updates, u) + } +} + +func (m *migrationUtil) SetFetched(raw ...interface{}) { + m.rawData = append(m.rawData, raw...) } func (m *migrationUtil) GetStats() MigrationStats { return MigrationStats{ Errored: m.errorsCount, + Fetched: len(m.rawData), ToApply: len(m.updates), Applied: m.updatedCount, Elapsed: time.Since(m.startedAt).Truncate(time.Millisecond), @@ -132,6 +143,10 @@ func (m *migrationUtil) GetStats() MigrationStats { } func (c MigrationStats) report() { + if c.Applied == 0 && c.Fetched > 0 { + log.Printf("elapsed [%s] for [%d] items fetched with [%d] errors\n", c.Elapsed, c.Fetched, c.Errored) + return + } log.Printf("elapsed [%s] for [%d] items migrated with [%d] errors\n", c.Elapsed, c.Applied, c.Errored) } diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index e6218760ab..034ca46d64 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -2,12 +2,16 @@ package utils import ( "encoding/json" + cErrors "errors" + "fmt" "log" "slices" + "strconv" "strings" "go.mongodb.org/mongo-driver/bson" + "github.com/tidepool-org/platform/data" "github.com/tidepool-org/platform/data/deduplicator/deduplicator" "github.com/tidepool-org/platform/data/normalizer" "github.com/tidepool-org/platform/data/types" @@ -20,6 +24,12 @@ import ( "github.com/tidepool-org/platform/data/types/device" "github.com/tidepool-org/platform/data/types/settings/pump" "github.com/tidepool-org/platform/errors" + "github.com/tidepool-org/platform/metadata" + + dataNormalizer "github.com/tidepool-org/platform/data/normalizer" + dataTypesFactory "github.com/tidepool-org/platform/data/types/factory" + structureParser "github.com/tidepool-org/platform/structure/parser" + structureValidator "github.com/tidepool-org/platform/structure/validator" ) func updateIfExistsPumpSettingsSleepSchedules(bsonData bson.M) (*pump.SleepScheduleMap, error) { @@ -65,6 +75,64 @@ func pumpSettingsHasBolus(bsonData bson.M) bool { return false } +func ProcessData(rawDatumArray []interface{}) ([]data.Datum, error) { + + preprocessedDatumArray := []interface{}{} + + for _, rawDatum := range rawDatumArray { + item := rawDatum.(map[string]interface{}) + if fmt.Sprintf("%v", item["type"]) == pump.Type { + if boluses := item["bolus"]; boluses != nil { + item["boluses"] = boluses + delete(item, "bolus") + } + } + if payload := item["payload"]; payload != nil { + if payloadMetadata, ok := payload.(*metadata.Metadata); ok { + item["payload"] = payloadMetadata + } + } + if annotations := item["annotations"]; annotations != nil { + if metadataArray, ok := annotations.(*metadata.MetadataArray); ok { + item["annotations"] = metadataArray + } + } + preprocessedDatumArray = append(preprocessedDatumArray, item) + } + + var processErr error + parser := structureParser.NewArray(&preprocessedDatumArray) + validator := structureValidator.New() + normalizer := dataNormalizer.New() + + datumArray := []data.Datum{} + for _, reference := range parser.References() { + if datum := dataTypesFactory.ParseDatum(parser.WithReferenceObjectParser(reference)); datum != nil && *datum != nil { + (*datum).Validate(validator.WithReference(strconv.Itoa(reference))) + (*datum).Normalize(normalizer.WithReference(strconv.Itoa(reference))) + datumArray = append(datumArray, *datum) + } + } + + if err := parser.NotParsed(); err != nil { + processErr = cErrors.Join(processErr, err) + } + + if err := parser.Error(); err != nil { + processErr = cErrors.Join(processErr, err) + } + + if err := validator.Error(); err != nil { + processErr = cErrors.Join(processErr, err) + } + + if err := normalizer.Error(); err != nil { + processErr = cErrors.Join(processErr, err) + } + + return datumArray, processErr +} + func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { updates := []bson.M{} set := bson.M{} From c81b870d6f381ac0e3b71f2e3b3405661e4c84c9 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 25 Jan 2024 14:38:35 +1300 Subject: [PATCH 125/413] datatype update for raw data --- .../20231128_jellyfish_migration/jellyfish_migration.go | 2 +- migrations/20231128_jellyfish_migration/utils/utils.go | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 43b6c0247c..297d5cd8b4 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -308,7 +308,7 @@ func (m *Migration) fetchAndProcess() bool { } defer dDataCursor.Close(m.ctx) - results := []interface{}{} + results := []map[string]interface{}{} if err := dDataCursor.All(m.ctx, &results); err != nil { log.Printf("error decoding data: %s", err) return false diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 034ca46d64..71df5448b3 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -75,12 +75,11 @@ func pumpSettingsHasBolus(bsonData bson.M) bool { return false } -func ProcessData(rawDatumArray []interface{}) ([]data.Datum, error) { +func ProcessData(rawDatumArray []map[string]interface{}) ([]data.Datum, error) { preprocessedDatumArray := []interface{}{} - for _, rawDatum := range rawDatumArray { - item := rawDatum.(map[string]interface{}) + for _, item := range rawDatumArray { if fmt.Sprintf("%v", item["type"]) == pump.Type { if boluses := item["bolus"]; boluses != nil { item["boluses"] = boluses From ba76fe62cee110587808dac9e613412db221002a Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 25 Jan 2024 14:47:55 +1300 Subject: [PATCH 126/413] timings --- migrations/20231128_jellyfish_migration/utils/utils.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 71df5448b3..315c028573 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -8,6 +8,7 @@ import ( "slices" "strconv" "strings" + "time" "go.mongodb.org/mongo-driver/bson" @@ -77,6 +78,8 @@ func pumpSettingsHasBolus(bsonData bson.M) bool { func ProcessData(rawDatumArray []map[string]interface{}) ([]data.Datum, error) { + start := time.Now() + preprocessedDatumArray := []interface{}{} for _, item := range rawDatumArray { @@ -129,6 +132,8 @@ func ProcessData(rawDatumArray []map[string]interface{}) ([]data.Datum, error) { processErr = cErrors.Join(processErr, err) } + log.Printf("processed [%d] in [%s] [%t]", len(datumArray), time.Since(start).Truncate(time.Millisecond), processErr != nil) + return datumArray, processErr } From a1f5f787ca74a181aa62ac4d361ff75b558af877 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 25 Jan 2024 15:13:07 +1300 Subject: [PATCH 127/413] report on audit --- .../jellyfish_migration.go | 6 ++++-- .../utils/utils.go | 19 ++++++++----------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 297d5cd8b4..c0d9f98f0a 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -313,8 +313,10 @@ func (m *Migration) fetchAndProcess() bool { log.Printf("error decoding data: %s", err) return false } - if _, err := utils.ProcessData(results); err != nil { - m.migrationUtil.OnError(err, "", "processing data") + if _, errs := utils.ProcessData(results); errs != nil { + for _, err := range errs { + m.migrationUtil.OnError(err, "", "processing data") + } } m.migrationUtil.SetFetched(results) return len(results) > 0 diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 315c028573..80bbb9df1e 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -2,7 +2,6 @@ package utils import ( "encoding/json" - cErrors "errors" "fmt" "log" "slices" @@ -76,7 +75,7 @@ func pumpSettingsHasBolus(bsonData bson.M) bool { return false } -func ProcessData(rawDatumArray []map[string]interface{}) ([]data.Datum, error) { +func ProcessData(rawDatumArray []map[string]interface{}) ([]data.Datum, []error) { start := time.Now() @@ -102,7 +101,7 @@ func ProcessData(rawDatumArray []map[string]interface{}) ([]data.Datum, error) { preprocessedDatumArray = append(preprocessedDatumArray, item) } - var processErr error + errs := []error{} parser := structureParser.NewArray(&preprocessedDatumArray) validator := structureValidator.New() normalizer := dataNormalizer.New() @@ -116,25 +115,23 @@ func ProcessData(rawDatumArray []map[string]interface{}) ([]data.Datum, error) { } } - if err := parser.NotParsed(); err != nil { - processErr = cErrors.Join(processErr, err) - } + parser.NotParsed() if err := parser.Error(); err != nil { - processErr = cErrors.Join(processErr, err) + errs = append(errs, err) } if err := validator.Error(); err != nil { - processErr = cErrors.Join(processErr, err) + errs = append(errs, err) } if err := normalizer.Error(); err != nil { - processErr = cErrors.Join(processErr, err) + errs = append(errs, err) } - log.Printf("processed [%d] in [%s] [%t]", len(datumArray), time.Since(start).Truncate(time.Millisecond), processErr != nil) + log.Printf("processed [%d] in [%s] [%t]", len(datumArray), time.Since(start).Truncate(time.Millisecond), len(errs) > 0) - return datumArray, processErr + return datumArray, errs } func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { From 6c0acd4f3a3f8fb41bd5258ae7f64d56595631a6 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 25 Jan 2024 15:33:54 +1300 Subject: [PATCH 128/413] check fetch count against the cap also --- .../20231128_jellyfish_migration/utils/migrationUtil.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 7ec5cc02b6..bc95c60d59 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -112,9 +112,10 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe return err } if m.config.cap != nil { - if m.updatedCount >= *m.config.cap { + if m.updatedCount >= *m.config.cap || len(m.rawData) >= *m.config.cap { break } + } } m.GetStats().report() @@ -398,6 +399,7 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio return errors.New("missing required collection to write updates to") } if len(m.updates) == 0 { + log.Println("no updates to apply") return nil } From 929181d340eb71b658bedbdd5b3e5bdbb13810a7 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 25 Jan 2024 15:35:55 +1300 Subject: [PATCH 129/413] just validate and normalizer errs --- migrations/20231128_jellyfish_migration/utils/utils.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 80bbb9df1e..0d7b83e886 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -117,9 +117,9 @@ func ProcessData(rawDatumArray []map[string]interface{}) ([]data.Datum, []error) parser.NotParsed() - if err := parser.Error(); err != nil { - errs = append(errs, err) - } + // if err := parser.Error(); err != nil { + // errs = append(errs, err) + // } if err := validator.Error(); err != nil { errs = append(errs, err) From 99eecbe3eb24fa4c8f8662b3062ca3da41723667 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 25 Jan 2024 15:49:36 +1300 Subject: [PATCH 130/413] check cap --- .../utils/migrationUtil.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index bc95c60d59..9ebe7d7aee 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -105,17 +105,23 @@ func (m *migrationUtil) Initialize(ctx context.Context, dataC *mongo.Collection) return nil } +func (m *migrationUtil) capReached() bool { + stats := m.GetStats() + log.Printf("cap [%d] updated [%d] fetched [%d]", *m.config.cap, stats.Applied, stats.Fetched) + if *m.config.cap >= stats.Applied || *m.config.cap >= stats.Fetched { + return true + } + return false +} + func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func() bool) error { for fetchAndUpdateFn() { if err := m.writeUpdates(ctx, dataC); err != nil { log.Printf("failed writing batch: %s", err) return err } - if m.config.cap != nil { - if m.updatedCount >= *m.config.cap || len(m.rawData) >= *m.config.cap { - break - } - + if m.capReached() { + break } } m.GetStats().report() From 92dfa8668ec4a6de71dc8e71c1d15cd5ef8db2a9 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 25 Jan 2024 16:17:11 +1300 Subject: [PATCH 131/413] data fetch summary --- migrations/20231128_jellyfish_migration/utils/migrationUtil.go | 1 + migrations/20231128_jellyfish_migration/utils/utils.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 9ebe7d7aee..0d2b7407ce 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -137,6 +137,7 @@ func (m *migrationUtil) SetUpdates(lastID string, update ...*mongo.UpdateOneMode func (m *migrationUtil) SetFetched(raw ...interface{}) { m.rawData = append(m.rawData, raw...) + log.Printf("fetched [%d]", len(m.rawData)) } func (m *migrationUtil) GetStats() MigrationStats { diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 0d7b83e886..cd83d8d0fc 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -129,7 +129,7 @@ func ProcessData(rawDatumArray []map[string]interface{}) ([]data.Datum, []error) errs = append(errs, err) } - log.Printf("processed [%d] in [%s] [%t]", len(datumArray), time.Since(start).Truncate(time.Millisecond), len(errs) > 0) + log.Printf("processed [%d] in [%s] [%t]", len(rawDatumArray), time.Since(start).Truncate(time.Millisecond), len(errs) > 0) return datumArray, errs } From 6cebb7191a02b298c9698a4c0d83ae6ae618389d Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 25 Jan 2024 16:37:21 +1300 Subject: [PATCH 132/413] get parser errors too --- .../20231128_jellyfish_migration/jellyfish_migration.go | 2 +- .../20231128_jellyfish_migration/utils/migrationUtil.go | 8 ++++---- migrations/20231128_jellyfish_migration/utils/utils.go | 8 +++++--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index c0d9f98f0a..a2f27f0354 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -313,12 +313,12 @@ func (m *Migration) fetchAndProcess() bool { log.Printf("error decoding data: %s", err) return false } + m.migrationUtil.SetFetched(results) if _, errs := utils.ProcessData(results); errs != nil { for _, err := range errs { m.migrationUtil.OnError(err, "", "processing data") } } - m.migrationUtil.SetFetched(results) return len(results) > 0 } return false diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 0d2b7407ce..1124ac3d55 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -40,7 +40,7 @@ type migrationUtil struct { client *mongo.Client config *MigrationUtilConfig updates []mongo.WriteModel - rawData []interface{} + rawData []map[string]interface{} errorsCount int updatedCount int lastUpdatedId string @@ -60,7 +60,7 @@ type MigrationUtil interface { Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func() bool) error OnError(reportErr error, id string, msg string) SetUpdates(lastID string, update ...*mongo.UpdateOneModel) - SetFetched(raw ...interface{}) + SetFetched(raw []map[string]interface{}) GetLastID() string GetStats() MigrationStats } @@ -84,7 +84,7 @@ func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client, lastID client: client, config: config, updates: []mongo.WriteModel{}, - rawData: []interface{}{}, + rawData: []map[string]interface{}{}, errorsCount: 0, updatedCount: 0, startedAt: time.Now(), @@ -135,7 +135,7 @@ func (m *migrationUtil) SetUpdates(lastID string, update ...*mongo.UpdateOneMode } } -func (m *migrationUtil) SetFetched(raw ...interface{}) { +func (m *migrationUtil) SetFetched(raw []map[string]interface{}) { m.rawData = append(m.rawData, raw...) log.Printf("fetched [%d]", len(m.rawData)) } diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index cd83d8d0fc..5ca13493f8 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -79,6 +79,8 @@ func ProcessData(rawDatumArray []map[string]interface{}) ([]data.Datum, []error) start := time.Now() + log.Printf("to process [%d] datums", len(rawDatumArray)) + preprocessedDatumArray := []interface{}{} for _, item := range rawDatumArray { @@ -117,9 +119,9 @@ func ProcessData(rawDatumArray []map[string]interface{}) ([]data.Datum, []error) parser.NotParsed() - // if err := parser.Error(); err != nil { - // errs = append(errs, err) - // } + if err := parser.Error(); err != nil { + errs = append(errs, err) + } if err := validator.Error(); err != nil { errs = append(errs, err) From 4fc20c905080d82179b9e9f92d7863827468e53a Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 25 Jan 2024 16:51:25 +1300 Subject: [PATCH 133/413] moar debug --- migrations/20231128_jellyfish_migration/utils/utils.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 5ca13493f8..60a1273aed 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -83,7 +83,10 @@ func ProcessData(rawDatumArray []map[string]interface{}) ([]data.Datum, []error) preprocessedDatumArray := []interface{}{} - for _, item := range rawDatumArray { + for i, item := range rawDatumArray { + + log.Printf("[%d] [%v]\n\n", i, item) + if fmt.Sprintf("%v", item["type"]) == pump.Type { if boluses := item["bolus"]; boluses != nil { item["boluses"] = boluses @@ -111,6 +114,7 @@ func ProcessData(rawDatumArray []map[string]interface{}) ([]data.Datum, []error) datumArray := []data.Datum{} for _, reference := range parser.References() { if datum := dataTypesFactory.ParseDatum(parser.WithReferenceObjectParser(reference)); datum != nil && *datum != nil { + log.Printf("Datum: [%d] [%v]\n\n", reference, datum) (*datum).Validate(validator.WithReference(strconv.Itoa(reference))) (*datum).Normalize(normalizer.WithReference(strconv.Itoa(reference))) datumArray = append(datumArray, *datum) From bb504cebfc24d7dea4502a9861426abb7ea4031f Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 25 Jan 2024 17:06:13 +1300 Subject: [PATCH 134/413] debug --- .../20231128_jellyfish_migration/utils/migrationUtil.go | 2 +- migrations/20231128_jellyfish_migration/utils/utils.go | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 1124ac3d55..0666c1c3e9 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -108,7 +108,7 @@ func (m *migrationUtil) Initialize(ctx context.Context, dataC *mongo.Collection) func (m *migrationUtil) capReached() bool { stats := m.GetStats() log.Printf("cap [%d] updated [%d] fetched [%d]", *m.config.cap, stats.Applied, stats.Fetched) - if *m.config.cap >= stats.Applied || *m.config.cap >= stats.Fetched { + if *m.config.cap < stats.Applied || *m.config.cap < stats.Fetched { return true } return false diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 60a1273aed..4d233a509f 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -79,8 +79,6 @@ func ProcessData(rawDatumArray []map[string]interface{}) ([]data.Datum, []error) start := time.Now() - log.Printf("to process [%d] datums", len(rawDatumArray)) - preprocessedDatumArray := []interface{}{} for i, item := range rawDatumArray { @@ -114,7 +112,7 @@ func ProcessData(rawDatumArray []map[string]interface{}) ([]data.Datum, []error) datumArray := []data.Datum{} for _, reference := range parser.References() { if datum := dataTypesFactory.ParseDatum(parser.WithReferenceObjectParser(reference)); datum != nil && *datum != nil { - log.Printf("Datum: [%d] [%v]\n\n", reference, datum) + log.Printf("Datum: [%d] [%v]\n\n", reference, *datum) (*datum).Validate(validator.WithReference(strconv.Itoa(reference))) (*datum).Normalize(normalizer.WithReference(strconv.Itoa(reference))) datumArray = append(datumArray, *datum) From 70c01cf9491b7177822ac67316b49c9b2e39e02e Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 25 Jan 2024 18:02:47 +1300 Subject: [PATCH 135/413] convert from bson to type --- .../jellyfish_migration.go | 11 +-- .../utils/migrationUtil.go | 8 +- .../utils/utils.go | 77 +++++++++++++++---- 3 files changed, 73 insertions(+), 23 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index a2f27f0354..59ad7ea5a6 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -308,18 +308,19 @@ func (m *Migration) fetchAndProcess() bool { } defer dDataCursor.Close(m.ctx) - results := []map[string]interface{}{} - if err := dDataCursor.All(m.ctx, &results); err != nil { + items := []bson.M{} + //results := []map[string]interface{}{} + if err := dDataCursor.All(m.ctx, &items); err != nil { log.Printf("error decoding data: %s", err) return false } - m.migrationUtil.SetFetched(results) - if _, errs := utils.ProcessData(results); errs != nil { + m.migrationUtil.SetFetched(items) + if _, errs := utils.ProcessData(items); errs != nil { for _, err := range errs { m.migrationUtil.OnError(err, "", "processing data") } } - return len(results) > 0 + return len(items) > 0 } return false } diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 0666c1c3e9..8a1a608b10 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -40,7 +40,7 @@ type migrationUtil struct { client *mongo.Client config *MigrationUtilConfig updates []mongo.WriteModel - rawData []map[string]interface{} + rawData []bson.M errorsCount int updatedCount int lastUpdatedId string @@ -60,7 +60,7 @@ type MigrationUtil interface { Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func() bool) error OnError(reportErr error, id string, msg string) SetUpdates(lastID string, update ...*mongo.UpdateOneModel) - SetFetched(raw []map[string]interface{}) + SetFetched(raw []bson.M) GetLastID() string GetStats() MigrationStats } @@ -84,7 +84,7 @@ func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client, lastID client: client, config: config, updates: []mongo.WriteModel{}, - rawData: []map[string]interface{}{}, + rawData: []bson.M{}, errorsCount: 0, updatedCount: 0, startedAt: time.Now(), @@ -135,7 +135,7 @@ func (m *migrationUtil) SetUpdates(lastID string, update ...*mongo.UpdateOneMode } } -func (m *migrationUtil) SetFetched(raw []map[string]interface{}) { +func (m *migrationUtil) SetFetched(raw []bson.M) { m.rawData = append(m.rawData, raw...) log.Printf("fetched [%d]", len(m.rawData)) } diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 4d233a509f..fa09820fbe 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -27,7 +27,6 @@ import ( "github.com/tidepool-org/platform/metadata" dataNormalizer "github.com/tidepool-org/platform/data/normalizer" - dataTypesFactory "github.com/tidepool-org/platform/data/types/factory" structureParser "github.com/tidepool-org/platform/structure/parser" structureValidator "github.com/tidepool-org/platform/structure/validator" ) @@ -75,22 +74,25 @@ func pumpSettingsHasBolus(bsonData bson.M) bool { return false } -func ProcessData(rawDatumArray []map[string]interface{}) ([]data.Datum, []error) { +func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { start := time.Now() preprocessedDatumArray := []interface{}{} + datumArray := []data.Datum{} - for i, item := range rawDatumArray { + for i, item := range bsonDataArray { - log.Printf("[%d] [%v]\n\n", i, item) + dType := fmt.Sprintf("%v", item["type"]) - if fmt.Sprintf("%v", item["type"]) == pump.Type { + // FIX + if dType == pump.Type { if boluses := item["bolus"]; boluses != nil { item["boluses"] = boluses delete(item, "bolus") } } + if payload := item["payload"]; payload != nil { if payloadMetadata, ok := payload.(*metadata.Metadata); ok { item["payload"] = payloadMetadata @@ -101,6 +103,49 @@ func ProcessData(rawDatumArray []map[string]interface{}) ([]data.Datum, []error) item["annotations"] = metadataArray } } + + log.Printf("[%d] [%v]\n\n", i, item) + + // + switch dType { + case pump.Type: + var datum *pump.Pump + dataBytes, err := bson.Marshal(item) + if err != nil { + log.Printf("%s %s", dType, err) + break + } + err = bson.Unmarshal(dataBytes, &datum) + if err != nil { + log.Printf("%s %s", dType, err) + } + datumArray = append(datumArray, datum) + case continuous.Type: + var datum *continuous.Continuous + dataBytes, err := bson.Marshal(item) + if err != nil { + log.Printf("%s %s", dType, err) + break + } + err = bson.Unmarshal(dataBytes, &datum) + if err != nil { + log.Printf("%s %s", dType, err) + } + datumArray = append(datumArray, datum) + + case selfmonitored.Type: + var datum *selfmonitored.SelfMonitored + dataBytes, err := bson.Marshal(item) + if err != nil { + log.Printf("%s %s", dType, err) + break + } + err = bson.Unmarshal(dataBytes, &datum) + if err != nil { + log.Printf("%s %s", dType, err) + } + datumArray = append(datumArray, datum) + } preprocessedDatumArray = append(preprocessedDatumArray, item) } @@ -109,14 +154,18 @@ func ProcessData(rawDatumArray []map[string]interface{}) ([]data.Datum, []error) validator := structureValidator.New() normalizer := dataNormalizer.New() - datumArray := []data.Datum{} - for _, reference := range parser.References() { - if datum := dataTypesFactory.ParseDatum(parser.WithReferenceObjectParser(reference)); datum != nil && *datum != nil { - log.Printf("Datum: [%d] [%v]\n\n", reference, *datum) - (*datum).Validate(validator.WithReference(strconv.Itoa(reference))) - (*datum).Normalize(normalizer.WithReference(strconv.Itoa(reference))) - datumArray = append(datumArray, *datum) - } + // for _, reference := range parser.References() { + // if datum := dataTypesFactory.ParseDatum(parser.WithReferenceObjectParser(reference)); datum != nil && *datum != nil { + // log.Printf("Datum: [%d] [%v]\n\n", reference, *datum) + // (*datum).Validate(validator.WithReference(strconv.Itoa(reference))) + // (*datum).Normalize(normalizer.WithReference(strconv.Itoa(reference))) + // datumArray = append(datumArray, *datum) + // } + // } + + for i, datum := range datumArray { + (datum).Validate(validator.WithReference(strconv.Itoa(i))) + (datum).Normalize(normalizer.WithReference(strconv.Itoa(i))) } parser.NotParsed() @@ -133,7 +182,7 @@ func ProcessData(rawDatumArray []map[string]interface{}) ([]data.Datum, []error) errs = append(errs, err) } - log.Printf("processed [%d] in [%s] [%t]", len(rawDatumArray), time.Since(start).Truncate(time.Millisecond), len(errs) > 0) + log.Printf("processed [%d] in [%s] [%t]", len(bsonDataArray), time.Since(start).Truncate(time.Millisecond), len(errs) > 0) return datumArray, errs } From 530f4478c4a91c5cbf2d779af47a973e1b785921 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 25 Jan 2024 18:10:31 +1300 Subject: [PATCH 136/413] cleanup --- .../utils/utils.go | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index fa09820fbe..c3062a3174 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -27,7 +27,6 @@ import ( "github.com/tidepool-org/platform/metadata" dataNormalizer "github.com/tidepool-org/platform/data/normalizer" - structureParser "github.com/tidepool-org/platform/structure/parser" structureValidator "github.com/tidepool-org/platform/structure/validator" ) @@ -78,7 +77,7 @@ func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { start := time.Now() - preprocessedDatumArray := []interface{}{} + //preprocessedDatumArray := []interface{}{} datumArray := []data.Datum{} for i, item := range bsonDataArray { @@ -118,6 +117,7 @@ func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { err = bson.Unmarshal(dataBytes, &datum) if err != nil { log.Printf("%s %s", dType, err) + break } datumArray = append(datumArray, datum) case continuous.Type: @@ -130,6 +130,7 @@ func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { err = bson.Unmarshal(dataBytes, &datum) if err != nil { log.Printf("%s %s", dType, err) + break } datumArray = append(datumArray, datum) @@ -143,14 +144,15 @@ func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { err = bson.Unmarshal(dataBytes, &datum) if err != nil { log.Printf("%s %s", dType, err) + break } datumArray = append(datumArray, datum) } - preprocessedDatumArray = append(preprocessedDatumArray, item) + //preprocessedDatumArray = append(preprocessedDatumArray, item) } errs := []error{} - parser := structureParser.NewArray(&preprocessedDatumArray) + //parser := structureParser.NewArray(&preprocessedDatumArray) validator := structureValidator.New() normalizer := dataNormalizer.New() @@ -168,11 +170,11 @@ func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { (datum).Normalize(normalizer.WithReference(strconv.Itoa(i))) } - parser.NotParsed() + // parser.NotParsed() - if err := parser.Error(); err != nil { - errs = append(errs, err) - } + // if err := parser.Error(); err != nil { + // errs = append(errs, err) + // } if err := validator.Error(); err != nil { errs = append(errs, err) @@ -182,7 +184,7 @@ func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { errs = append(errs, err) } - log.Printf("processed [%d] in [%s] [%t]", len(bsonDataArray), time.Since(start).Truncate(time.Millisecond), len(errs) > 0) + log.Printf("fetched [%d] processed [%d] in [%s] [%t]", len(bsonDataArray), len(datumArray), time.Since(start).Truncate(time.Millisecond), len(errs) > 0) return datumArray, errs } From 7e9c4aa789c8d65b98d7ca8e41b767ef2a38d09a Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 30 Jan 2024 08:57:01 +1300 Subject: [PATCH 137/413] converted json data --- migrations/20231128_jellyfish_migration/utils/utils.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index c3062a3174..8b5421c6b0 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -77,14 +77,18 @@ func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { start := time.Now() - //preprocessedDatumArray := []interface{}{} datumArray := []data.Datum{} - for i, item := range bsonDataArray { + jsonData, _ := json.Marshal(bsonDataArray) + converted := []map[string]interface{}{} + + json.Unmarshal(jsonData, &converted) + + for i, item := range converted { dType := fmt.Sprintf("%v", item["type"]) - // FIX + // FIXES if dType == pump.Type { if boluses := item["bolus"]; boluses != nil { item["boluses"] = boluses From d0a6cb49adb66b4167b99aaa700bb6705a357434 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 30 Jan 2024 09:24:19 +1300 Subject: [PATCH 138/413] via dataTypesFactory parser --- .../utils/utils.go | 130 ++++++++++-------- 1 file changed, 69 insertions(+), 61 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 8b5421c6b0..903f060952 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -27,6 +27,8 @@ import ( "github.com/tidepool-org/platform/metadata" dataNormalizer "github.com/tidepool-org/platform/data/normalizer" + dataTypesFactory "github.com/tidepool-org/platform/data/types/factory" + structureParser "github.com/tidepool-org/platform/structure/parser" structureValidator "github.com/tidepool-org/platform/structure/validator" ) @@ -81,10 +83,11 @@ func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { jsonData, _ := json.Marshal(bsonDataArray) converted := []map[string]interface{}{} + preprocessedDatumArray := []interface{}{} json.Unmarshal(jsonData, &converted) - for i, item := range converted { + for _, item := range converted { dType := fmt.Sprintf("%v", item["type"]) @@ -107,84 +110,89 @@ func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { } } - log.Printf("[%d] [%v]\n\n", i, item) + //log.Printf("[%d] [%v]\n\n", i, item) // - switch dType { - case pump.Type: - var datum *pump.Pump - dataBytes, err := bson.Marshal(item) - if err != nil { - log.Printf("%s %s", dType, err) - break - } - err = bson.Unmarshal(dataBytes, &datum) - if err != nil { - log.Printf("%s %s", dType, err) - break - } - datumArray = append(datumArray, datum) - case continuous.Type: - var datum *continuous.Continuous - dataBytes, err := bson.Marshal(item) - if err != nil { - log.Printf("%s %s", dType, err) - break - } - err = bson.Unmarshal(dataBytes, &datum) - if err != nil { - log.Printf("%s %s", dType, err) - break - } - datumArray = append(datumArray, datum) - - case selfmonitored.Type: - var datum *selfmonitored.SelfMonitored - dataBytes, err := bson.Marshal(item) - if err != nil { - log.Printf("%s %s", dType, err) - break - } - err = bson.Unmarshal(dataBytes, &datum) - if err != nil { - log.Printf("%s %s", dType, err) - break - } - datumArray = append(datumArray, datum) - } - //preprocessedDatumArray = append(preprocessedDatumArray, item) + // switch dType { + // case pump.Type: + // var datum *pump.Pump + // dataBytes, err := bson.Marshal(item) + // if err != nil { + // log.Printf("%s %s", dType, err) + // break + // } + // err = bson.Unmarshal(dataBytes, &datum) + // if err != nil { + // log.Printf("%s %s", dType, err) + // break + // } + // datumArray = append(datumArray, datum) + // case continuous.Type: + // var datum *continuous.Continuous + // dataBytes, err := bson.Marshal(item) + // if err != nil { + // log.Printf("%s %s", dType, err) + // break + // } + // err = bson.Unmarshal(dataBytes, &datum) + // if err != nil { + // log.Printf("%s %s", dType, err) + // break + // } + // datumArray = append(datumArray, datum) + + // case selfmonitored.Type: + // var datum *selfmonitored.SelfMonitored + // dataBytes, err := bson.Marshal(item) + // if err != nil { + // log.Printf("%s %s", dType, err) + // break + // } + // err = bson.Unmarshal(dataBytes, &datum) + // if err != nil { + // log.Printf("%s %s", dType, err) + // break + // } + // datumArray = append(datumArray, datum) + // default: + + // } + preprocessedDatumArray = append(preprocessedDatumArray, item) } errs := []error{} - //parser := structureParser.NewArray(&preprocessedDatumArray) + parser := structureParser.NewArray(&preprocessedDatumArray) validator := structureValidator.New() normalizer := dataNormalizer.New() - // for _, reference := range parser.References() { - // if datum := dataTypesFactory.ParseDatum(parser.WithReferenceObjectParser(reference)); datum != nil && *datum != nil { - // log.Printf("Datum: [%d] [%v]\n\n", reference, *datum) - // (*datum).Validate(validator.WithReference(strconv.Itoa(reference))) - // (*datum).Normalize(normalizer.WithReference(strconv.Itoa(reference))) - // datumArray = append(datumArray, *datum) - // } - // } - - for i, datum := range datumArray { - (datum).Validate(validator.WithReference(strconv.Itoa(i))) - (datum).Normalize(normalizer.WithReference(strconv.Itoa(i))) + for _, reference := range parser.References() { + if datum := dataTypesFactory.ParseDatum(parser.WithReferenceObjectParser(reference)); datum != nil && *datum != nil { + log.Printf("Datum: [%d] [%v]\n\n", reference, *datum) + (*datum).Validate(validator.WithReference(strconv.Itoa(reference))) + (*datum).Normalize(normalizer.WithReference(strconv.Itoa(reference))) + datumArray = append(datumArray, *datum) + } } + // for i, datum := range datumArray { + // (datum).Validate(validator.WithReference(strconv.Itoa(i))) + // (datum).Normalize(normalizer.WithReference(strconv.Itoa(i))) + // } + // parser.NotParsed() - // if err := parser.Error(); err != nil { - // errs = append(errs, err) - // } + if err := parser.Error(); err != nil { + log.Println("Parser errors") + errs = append(errs, err) + } if err := validator.Error(); err != nil { + log.Println("Validator errors") errs = append(errs, err) } if err := normalizer.Error(); err != nil { + log.Println("Normalizer errors") errs = append(errs, err) } From 46227d7ae64a555cef66216647f04e9447770d96 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 30 Jan 2024 09:50:43 +1300 Subject: [PATCH 139/413] log updates while debugging --- .../20231128_jellyfish_migration/utils/utils.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 903f060952..a0ee8ed238 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "log" + "os" "slices" "strconv" "strings" @@ -75,6 +76,19 @@ func pumpSettingsHasBolus(bsonData bson.M) bool { return false } +func logUpdates(datumArray []data.Datum) { + f, err := os.OpenFile("updated.log", + os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Println(err) + os.Exit(1) + } + defer f.Close() + for _, d := range datumArray { + f.WriteString(fmt.Sprintf("%v\n", d)) + } +} + func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { start := time.Now() @@ -196,6 +210,9 @@ func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { errs = append(errs, err) } + // for debug + logUpdates(datumArray) + log.Printf("fetched [%d] processed [%d] in [%s] [%t]", len(bsonDataArray), len(datumArray), time.Since(start).Truncate(time.Millisecond), len(errs) > 0) return datumArray, errs From 5a04407482e1d3708ac9d66c975b48cbd397b1f7 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 30 Jan 2024 10:11:44 +1300 Subject: [PATCH 140/413] write JSON --- migrations/20231128_jellyfish_migration/utils/utils.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index a0ee8ed238..45f14ede17 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -84,9 +84,8 @@ func logUpdates(datumArray []data.Datum) { os.Exit(1) } defer f.Close() - for _, d := range datumArray { - f.WriteString(fmt.Sprintf("%v\n", d)) - } + jsonData, _ := json.Marshal(datumArray) + f.WriteString(string(jsonData)) } func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { From 87964d8342c58ec498188665ac263d567834f326 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 30 Jan 2024 10:29:22 +1300 Subject: [PATCH 141/413] debug --- migrations/20231128_jellyfish_migration/utils/utils.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 45f14ede17..9dc62e432e 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -84,8 +84,11 @@ func logUpdates(datumArray []data.Datum) { os.Exit(1) } defer f.Close() - jsonData, _ := json.Marshal(datumArray) - f.WriteString(string(jsonData)) + for _, v := range datumArray { + fields, _ := v.IdentityFields() + f.WriteString(fmt.Sprintf("%s - %s \n", v.GetType(), fields)) + } + } func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { @@ -180,7 +183,6 @@ func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { for _, reference := range parser.References() { if datum := dataTypesFactory.ParseDatum(parser.WithReferenceObjectParser(reference)); datum != nil && *datum != nil { - log.Printf("Datum: [%d] [%v]\n\n", reference, *datum) (*datum).Validate(validator.WithReference(strconv.Itoa(reference))) (*datum).Normalize(normalizer.WithReference(strconv.Itoa(reference))) datumArray = append(datumArray, *datum) From b9544dfb34edaba865becee5a4798cb56c604386 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 30 Jan 2024 13:36:40 +1300 Subject: [PATCH 142/413] refine audit out put --- .../jellyfish_migration.go | 1 - .../utils/utils.go | 94 ++++--------------- 2 files changed, 17 insertions(+), 78 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 59ad7ea5a6..40ba02f4a4 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -309,7 +309,6 @@ func (m *Migration) fetchAndProcess() bool { defer dDataCursor.Close(m.ctx) items := []bson.M{} - //results := []map[string]interface{}{} if err := dDataCursor.All(m.ctx, &items); err != nil { log.Printf("error decoding data: %s", err) return false diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 9dc62e432e..9216ab12c8 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -14,7 +14,6 @@ import ( "github.com/tidepool-org/platform/data" "github.com/tidepool-org/platform/data/deduplicator/deduplicator" - "github.com/tidepool-org/platform/data/normalizer" "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/data/types/basal" "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" @@ -61,7 +60,7 @@ func updateIfExistsPumpSettingsSleepSchedules(bsonData bson.M) (*pump.SleepSched sleepScheduleMap[scheduleNames[i]] = schedule } //sorts schedules based on day - sleepScheduleMap.Normalize(normalizer.New()) + sleepScheduleMap.Normalize(dataNormalizer.New()) return &sleepScheduleMap, nil } return nil, nil @@ -77,7 +76,7 @@ func pumpSettingsHasBolus(bsonData bson.M) bool { } func logUpdates(datumArray []data.Datum) { - f, err := os.OpenFile("updated.log", + f, err := os.OpenFile("update.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { log.Println(err) @@ -86,16 +85,15 @@ func logUpdates(datumArray []data.Datum) { defer f.Close() for _, v := range datumArray { fields, _ := v.IdentityFields() - f.WriteString(fmt.Sprintf("%s - %s \n", v.GetType(), fields)) + f.WriteString(fmt.Sprintf("Type[%s] - IdentityFields[%v] \n", v.GetType(), fields)) } - } func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { start := time.Now() - datumArray := []data.Datum{} + data := []data.Datum{} jsonData, _ := json.Marshal(bsonDataArray) converted := []map[string]interface{}{} @@ -104,17 +102,14 @@ func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { json.Unmarshal(jsonData, &converted) for _, item := range converted { - dType := fmt.Sprintf("%v", item["type"]) - - // FIXES + // APPLY FIXES if dType == pump.Type { if boluses := item["bolus"]; boluses != nil { item["boluses"] = boluses delete(item, "bolus") } } - if payload := item["payload"]; payload != nil { if payloadMetadata, ok := payload.(*metadata.Metadata); ok { item["payload"] = payloadMetadata @@ -125,54 +120,6 @@ func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { item["annotations"] = metadataArray } } - - //log.Printf("[%d] [%v]\n\n", i, item) - - // - // switch dType { - // case pump.Type: - // var datum *pump.Pump - // dataBytes, err := bson.Marshal(item) - // if err != nil { - // log.Printf("%s %s", dType, err) - // break - // } - // err = bson.Unmarshal(dataBytes, &datum) - // if err != nil { - // log.Printf("%s %s", dType, err) - // break - // } - // datumArray = append(datumArray, datum) - // case continuous.Type: - // var datum *continuous.Continuous - // dataBytes, err := bson.Marshal(item) - // if err != nil { - // log.Printf("%s %s", dType, err) - // break - // } - // err = bson.Unmarshal(dataBytes, &datum) - // if err != nil { - // log.Printf("%s %s", dType, err) - // break - // } - // datumArray = append(datumArray, datum) - - // case selfmonitored.Type: - // var datum *selfmonitored.SelfMonitored - // dataBytes, err := bson.Marshal(item) - // if err != nil { - // log.Printf("%s %s", dType, err) - // break - // } - // err = bson.Unmarshal(dataBytes, &datum) - // if err != nil { - // log.Printf("%s %s", dType, err) - // break - // } - // datumArray = append(datumArray, datum) - // default: - - // } preprocessedDatumArray = append(preprocessedDatumArray, item) } @@ -185,38 +132,31 @@ func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { if datum := dataTypesFactory.ParseDatum(parser.WithReferenceObjectParser(reference)); datum != nil && *datum != nil { (*datum).Validate(validator.WithReference(strconv.Itoa(reference))) (*datum).Normalize(normalizer.WithReference(strconv.Itoa(reference))) - datumArray = append(datumArray, *datum) + data = append(data, *datum) } } - // for i, datum := range datumArray { - // (datum).Validate(validator.WithReference(strconv.Itoa(i))) - // (datum).Normalize(normalizer.WithReference(strconv.Itoa(i))) - // } - - // parser.NotParsed() + // get error also? + parser.NotParsed() if err := parser.Error(); err != nil { - log.Println("Parser errors") - errs = append(errs, err) + errs = append(errs, errors.Wrap(err, "parser error")) } if err := validator.Error(); err != nil { - log.Println("Validator errors") - errs = append(errs, err) + errs = append(errs, errors.Wrap(err, "validation error")) } if err := normalizer.Error(); err != nil { - log.Println("Normalizer errors") - errs = append(errs, err) + errs = append(errs, errors.Wrap(err, "normalizer error")) } // for debug - logUpdates(datumArray) + logUpdates(data) - log.Printf("fetched [%d] processed [%d] in [%s] [%t]", len(bsonDataArray), len(datumArray), time.Since(start).Truncate(time.Millisecond), len(errs) > 0) + log.Printf("fetched [%d] processed [%d] in [%s] [%t]", len(bsonDataArray), len(data), time.Since(start).Truncate(time.Millisecond), len(errs) > 0) - return datumArray, errs + return data, errs } func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { @@ -320,7 +260,7 @@ func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { } beforeVal := datum.Value beforeUnits := datum.Units - datum.Normalize(normalizer.New()) + datum.Normalize(dataNormalizer.New()) afterVal := datum.Value afterUnits := datum.Units if *beforeVal != *afterVal { @@ -345,7 +285,7 @@ func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { } beforeVal := datum.Value beforeUnits := datum.Units - datum.Normalize(normalizer.New()) + datum.Normalize(dataNormalizer.New()) afterVal := datum.Value afterUnits := datum.Units if *beforeVal != *afterVal { @@ -373,7 +313,7 @@ func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { // as these are both being used in the hash calc via the IdentityFields we want to persist these changes if they are infact updated. beforeVal := datum.Value beforeUnits := datum.Units - datum.Normalize(normalizer.New()) + datum.Normalize(dataNormalizer.New()) afterVal := datum.Value afterUnits := datum.Units if *beforeVal != *afterVal { From f14e8937cd15a21ffa6d979b61e90161912d9973 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 30 Jan 2024 16:25:26 +1300 Subject: [PATCH 143/413] rework so each item processed individually --- .../jellyfish_migration.go | 25 +- .../utils/utils.go | 213 ++++++++++++++---- 2 files changed, 183 insertions(+), 55 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 40ba02f4a4..793db47cfa 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -308,18 +308,23 @@ func (m *Migration) fetchAndProcess() bool { } defer dDataCursor.Close(m.ctx) - items := []bson.M{} - if err := dDataCursor.All(m.ctx, &items); err != nil { - log.Printf("error decoding data: %s", err) - return false - } - m.migrationUtil.SetFetched(items) - if _, errs := utils.ProcessData(items); errs != nil { - for _, err := range errs { - m.migrationUtil.OnError(err, "", "processing data") + all := []bson.M{} + + for dDataCursor.Next(m.ctx) { + + item := bson.M{} + if err := dDataCursor.Decode(&item); err != nil { + log.Printf("error decoding data: %s", err) + return false } + _, err := utils.ProcessDatum(item) + if err != nil { + m.migrationUtil.OnError(err, fmt.Sprintf("%v", item["_id"]), "processing datum") + } + } - return len(items) > 0 + m.migrationUtil.SetFetched(all) + return len(all) > 0 } return false } diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 9216ab12c8..6af9d3e581 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -1,14 +1,13 @@ package utils import ( + "bytes" "encoding/json" "fmt" "log" "os" "slices" - "strconv" "strings" - "time" "go.mongodb.org/mongo-driver/bson" @@ -75,7 +74,7 @@ func pumpSettingsHasBolus(bsonData bson.M) bool { return false } -func logUpdates(datumArray []data.Datum) { +func logUpdates(updatesJSON []byte) { f, err := os.OpenFile("update.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { @@ -83,80 +82,204 @@ func logUpdates(datumArray []data.Datum) { os.Exit(1) } defer f.Close() - for _, v := range datumArray { - fields, _ := v.IdentityFields() - f.WriteString(fmt.Sprintf("Type[%s] - IdentityFields[%v] \n", v.GetType(), fields)) + buf := &bytes.Buffer{} + if err := json.Indent(buf, updatesJSON, "", "\t"); err == nil { + f.WriteString(fmt.Sprintf("%s \n", buf.String())) } } -func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { +// func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { - start := time.Now() +// errs := []error{} +// start := time.Now() - data := []data.Datum{} +// jsonData, err := json.Marshal(bsonDataArray) +// if err != nil { +// errs = append(errs, err) +// return nil, errs +// } +// converted := []map[string]interface{}{} +// //preprocessedDatumArray := []map[string]interface{}{} - jsonData, _ := json.Marshal(bsonDataArray) - converted := []map[string]interface{}{} - preprocessedDatumArray := []interface{}{} +// if err := json.Unmarshal(jsonData, &converted); err != nil { - json.Unmarshal(jsonData, &converted) +// } - for _, item := range converted { - dType := fmt.Sprintf("%v", item["type"]) - // APPLY FIXES - if dType == pump.Type { - if boluses := item["bolus"]; boluses != nil { - item["boluses"] = boluses - delete(item, "bolus") - } +// for _, item := range bsonDataArray { +// dType := fmt.Sprintf("%v", item["type"]) +// // APPLY FIXES +// if dType == pump.Type { +// if boluses := item["bolus"]; boluses != nil { +// item["boluses"] = boluses +// delete(item, "bolus") +// } +// } +// if payload := item["payload"]; payload != nil { + +// // if type is string decode as json then encode to metadata.Metadata +// if payloadMetadata, ok := payload.(*metadata.Metadata); ok { +// item["payload"] = payloadMetadata +// } +// } +// if annotations := item["annotations"]; annotations != nil { +// // as above +// if metadataArray, ok := annotations.(*metadata.MetadataArray); ok { +// item["annotations"] = metadataArray +// } +// } + +// //bsonDataArray[i] = item + +// //preprocessedDatumArray = append(preprocessedDatumArray, item) +// } + +// //marshal to json pretty print as source of comparison + +// data := []data.Datum{} + +// // parser := structureParser.NewArray(&preprocessedDatumArray) +// // validator := structureValidator.New() +// // normalizer := dataNormalizer.New() + +// //loop throuh + +// for index, preprocessedDatumObj := range preprocessedDatumArray { + +// parser := structureParser.NewObject(&preprocessedDatumObj) +// validator := structureValidator.New() +// normalizer := dataNormalizer.New() + +// //for _, reference := range parser.References() { +// if datum := dataTypesFactory.ParseDatum(parser.WithReferenceObjectParser(strconv.Itoa(index))); datum != nil && *datum != nil { +// (*datum).Validate(validator.WithReference(strconv.Itoa(index))) +// (*datum).Normalize(normalizer.WithReference(strconv.Itoa(index))) +// data = append(data, *datum) +// } else { +// data = append(data, nil) +// } +// //} +// //} + +// parser.NotParsed() + +// if err := parser.Error(); err != nil { +// errs = append(errs, errors.Wrap(err, "parser error")) +// continue +// } + +// if err := validator.Error(); err != nil { +// errs = append(errs, errors.Wrap(err, "validation error")) +// continue +// } + +// if err := normalizer.Error(); err != nil { +// errs = append(errs, errors.Wrap(err, "normalizer error")) +// continue +// } + +// // compare JSON before and after ... + +// } + +// // compare JSON + +// // ecode processed object back to json + +// // json pretty print original vs updated - compare strings and display dif to log + +// // for debug +// logUpdates(data) + +// log.Printf("fetched [%d] processed [%d] in [%s] [%t]", len(bsonDataArray), len(data), time.Since(start).Truncate(time.Millisecond), len(errs) > 0) + +// return data, errs +// } + +func ProcessDatum(bsonData bson.M) (data.Datum, error) { + + dType := fmt.Sprintf("%v", bsonData["type"]) + if dType == pump.Type { + if boluses := bsonData["bolus"]; boluses != nil { + bsonData["boluses"] = boluses + delete(bsonData, "bolus") } - if payload := item["payload"]; payload != nil { - if payloadMetadata, ok := payload.(*metadata.Metadata); ok { - item["payload"] = payloadMetadata + } + if payload := bsonData["payload"]; payload != nil { + if _, ok := payload.(string); ok { + dataBytes, err := bson.Marshal(payload) + if err != nil { + return nil, err + } + var payloadMetadata metadata.Metadata + err = bson.Unmarshal(dataBytes, &payloadMetadata) + if err != nil { + return nil, err } + bsonData["payload"] = &payloadMetadata } - if annotations := item["annotations"]; annotations != nil { - if metadataArray, ok := annotations.(*metadata.MetadataArray); ok { - item["annotations"] = metadataArray + } + if annotations := bsonData["annotations"]; annotations != nil { + if _, ok := annotations.(string); ok { + dataBytes, err := bson.Marshal(annotations) + if err != nil { + return nil, err } + var metadataArray metadata.MetadataArray + err = bson.Unmarshal(dataBytes, &metadataArray) + if err != nil { + return nil, err + } + bsonData["annotations"] = &metadataArray } - preprocessedDatumArray = append(preprocessedDatumArray, item) } - errs := []error{} - parser := structureParser.NewArray(&preprocessedDatumArray) + //marshal to json pretty print as source of comparison + incomingJSONData, err := json.Marshal(bsonData) + if err != nil { + return nil, err + } + ojbData := map[string]interface{}{} + + if err := json.Unmarshal(incomingJSONData, &ojbData); err != nil { + return nil, err + } + + parser := structureParser.NewObject(&ojbData) validator := structureValidator.New() normalizer := dataNormalizer.New() - for _, reference := range parser.References() { - if datum := dataTypesFactory.ParseDatum(parser.WithReferenceObjectParser(reference)); datum != nil && *datum != nil { - (*datum).Validate(validator.WithReference(strconv.Itoa(reference))) - (*datum).Normalize(normalizer.WithReference(strconv.Itoa(reference))) - data = append(data, *datum) - } + datum := dataTypesFactory.ParseDatum(parser) + if datum != nil && *datum != nil { + (*datum).Validate(validator) + (*datum).Normalize(normalizer) + } else { + return nil, errors.Newf("no datum returned for id=[%s]", ojbData["_id"]) } - // get error also? parser.NotParsed() if err := parser.Error(); err != nil { - errs = append(errs, errors.Wrap(err, "parser error")) + return nil, err } if err := validator.Error(); err != nil { - errs = append(errs, errors.Wrap(err, "validation error")) + return nil, err } if err := normalizer.Error(); err != nil { - errs = append(errs, errors.Wrap(err, "normalizer error")) + return nil, err } - // for debug - logUpdates(data) - - log.Printf("fetched [%d] processed [%d] in [%s] [%t]", len(bsonDataArray), len(data), time.Since(start).Truncate(time.Millisecond), len(errs) > 0) + // compare JSON before and after ... + outgoingJSONData, err := json.Marshal(datum) + if err != nil { + return nil, err + } - return data, errs + if string(incomingJSONData) != string(outgoingJSONData) { + logUpdates(outgoingJSONData) + } + return *datum, nil } func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { From e7498ccb57178d6171ca195d42403576b89576e2 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 30 Jan 2024 16:53:17 +1300 Subject: [PATCH 144/413] update before and after --- .../jellyfish_migration.go | 2 +- .../utils/utils.go | 117 +----------------- 2 files changed, 7 insertions(+), 112 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 793db47cfa..bfa0ada0b4 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -319,7 +319,7 @@ func (m *Migration) fetchAndProcess() bool { } _, err := utils.ProcessDatum(item) if err != nil { - m.migrationUtil.OnError(err, fmt.Sprintf("%v", item["_id"]), "processing datum") + m.migrationUtil.OnError(err, fmt.Sprintf("%v", item["_id"]), fmt.Sprintf("type [%v]", item["type"])) } } diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 6af9d3e581..1bf5e7e6e4 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -88,113 +88,6 @@ func logUpdates(updatesJSON []byte) { } } -// func ProcessData(bsonDataArray []bson.M) ([]data.Datum, []error) { - -// errs := []error{} -// start := time.Now() - -// jsonData, err := json.Marshal(bsonDataArray) -// if err != nil { -// errs = append(errs, err) -// return nil, errs -// } -// converted := []map[string]interface{}{} -// //preprocessedDatumArray := []map[string]interface{}{} - -// if err := json.Unmarshal(jsonData, &converted); err != nil { - -// } - -// for _, item := range bsonDataArray { -// dType := fmt.Sprintf("%v", item["type"]) -// // APPLY FIXES -// if dType == pump.Type { -// if boluses := item["bolus"]; boluses != nil { -// item["boluses"] = boluses -// delete(item, "bolus") -// } -// } -// if payload := item["payload"]; payload != nil { - -// // if type is string decode as json then encode to metadata.Metadata -// if payloadMetadata, ok := payload.(*metadata.Metadata); ok { -// item["payload"] = payloadMetadata -// } -// } -// if annotations := item["annotations"]; annotations != nil { -// // as above -// if metadataArray, ok := annotations.(*metadata.MetadataArray); ok { -// item["annotations"] = metadataArray -// } -// } - -// //bsonDataArray[i] = item - -// //preprocessedDatumArray = append(preprocessedDatumArray, item) -// } - -// //marshal to json pretty print as source of comparison - -// data := []data.Datum{} - -// // parser := structureParser.NewArray(&preprocessedDatumArray) -// // validator := structureValidator.New() -// // normalizer := dataNormalizer.New() - -// //loop throuh - -// for index, preprocessedDatumObj := range preprocessedDatumArray { - -// parser := structureParser.NewObject(&preprocessedDatumObj) -// validator := structureValidator.New() -// normalizer := dataNormalizer.New() - -// //for _, reference := range parser.References() { -// if datum := dataTypesFactory.ParseDatum(parser.WithReferenceObjectParser(strconv.Itoa(index))); datum != nil && *datum != nil { -// (*datum).Validate(validator.WithReference(strconv.Itoa(index))) -// (*datum).Normalize(normalizer.WithReference(strconv.Itoa(index))) -// data = append(data, *datum) -// } else { -// data = append(data, nil) -// } -// //} -// //} - -// parser.NotParsed() - -// if err := parser.Error(); err != nil { -// errs = append(errs, errors.Wrap(err, "parser error")) -// continue -// } - -// if err := validator.Error(); err != nil { -// errs = append(errs, errors.Wrap(err, "validation error")) -// continue -// } - -// if err := normalizer.Error(); err != nil { -// errs = append(errs, errors.Wrap(err, "normalizer error")) -// continue -// } - -// // compare JSON before and after ... - -// } - -// // compare JSON - -// // ecode processed object back to json - -// // json pretty print original vs updated - compare strings and display dif to log - -// // for debug -// logUpdates(data) - -// log.Printf("fetched [%d] processed [%d] in [%s] [%t]", len(bsonDataArray), len(data), time.Since(start).Truncate(time.Millisecond), len(errs) > 0) - -// return data, errs -// } - func ProcessDatum(bsonData bson.M) (data.Datum, error) { dType := fmt.Sprintf("%v", bsonData["type"]) @@ -213,7 +106,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { var payloadMetadata metadata.Metadata err = bson.Unmarshal(dataBytes, &payloadMetadata) if err != nil { - return nil, err + return nil, errors.Newf("payload could not be set from %v ", string(dataBytes)) } bsonData["payload"] = &payloadMetadata } @@ -225,9 +118,8 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { return nil, err } var metadataArray metadata.MetadataArray - err = bson.Unmarshal(dataBytes, &metadataArray) - if err != nil { - return nil, err + if err := bson.Unmarshal(dataBytes, &metadataArray); err != nil { + return nil, errors.Newf("annotations could not be set from %v ", string(dataBytes)) } bsonData["annotations"] = &metadataArray } @@ -235,6 +127,9 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { //marshal to json pretty print as source of comparison incomingJSONData, err := json.Marshal(bsonData) + + logUpdates(incomingJSONData) + if err != nil { return nil, err } From ad8532a819c793636d93c95b9ee518a41e473b5e Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 30 Jan 2024 17:17:10 +1300 Subject: [PATCH 145/413] try and get all the errors for a datum --- .../utils/utils.go | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 1bf5e7e6e4..e5228abe8a 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -3,6 +3,7 @@ package utils import ( "bytes" "encoding/json" + "errors" "fmt" "log" "os" @@ -12,6 +13,7 @@ import ( "go.mongodb.org/mongo-driver/bson" "github.com/tidepool-org/platform/data" + "github.com/tidepool-org/platform/data/deduplicator/deduplicator" "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/data/types/basal" @@ -22,7 +24,7 @@ import ( "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/data/types/device" "github.com/tidepool-org/platform/data/types/settings/pump" - "github.com/tidepool-org/platform/errors" + errorsP "github.com/tidepool-org/platform/errors" "github.com/tidepool-org/platform/metadata" dataNormalizer "github.com/tidepool-org/platform/data/normalizer" @@ -51,7 +53,7 @@ func updateIfExistsPumpSettingsSleepSchedules(bsonData bson.M) (*pump.SleepSched updatedDays := []string{} for _, day := range *days { if !slices.Contains(common.DaysOfWeek(), strings.ToLower(day)) { - return nil, errors.Newf("pumpSettings.sleepSchedules has an invalid day of week %s", day) + return nil, errorsP.Newf("pumpSettings.sleepSchedules has an invalid day of week %s", day) } updatedDays = append(updatedDays, strings.ToLower(day)) } @@ -106,7 +108,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { var payloadMetadata metadata.Metadata err = bson.Unmarshal(dataBytes, &payloadMetadata) if err != nil { - return nil, errors.Newf("payload could not be set from %v ", string(dataBytes)) + return nil, errorsP.Newf("payload could not be set from %v ", string(dataBytes)) } bsonData["payload"] = &payloadMetadata } @@ -119,7 +121,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { } var metadataArray metadata.MetadataArray if err := bson.Unmarshal(dataBytes, &metadataArray); err != nil { - return nil, errors.Newf("annotations could not be set from %v ", string(dataBytes)) + return nil, errorsP.Newf("annotations could not be set from %v ", string(dataBytes)) } bsonData["annotations"] = &metadataArray } @@ -143,26 +145,31 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { validator := structureValidator.New() normalizer := dataNormalizer.New() + var parseErr error datum := dataTypesFactory.ParseDatum(parser) if datum != nil && *datum != nil { (*datum).Validate(validator) (*datum).Normalize(normalizer) } else { - return nil, errors.Newf("no datum returned for id=[%s]", ojbData["_id"]) + return nil, errorsP.Newf("no datum returned for id=[%s]", ojbData["_id"]) } parser.NotParsed() if err := parser.Error(); err != nil { - return nil, err + parseErr = errors.Join(parseErr, err) } if err := validator.Error(); err != nil { - return nil, err + parseErr = errors.Join(parseErr, err) } if err := normalizer.Error(); err != nil { - return nil, err + parseErr = errors.Join(parseErr, err) + } + + if parseErr != nil { + return nil, parseErr } // compare JSON before and after ... @@ -185,12 +192,12 @@ func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { datumID, ok := bsonData["_id"].(string) if !ok { - return "", nil, errors.New("cannot get the datum id") + return "", nil, errorsP.New("cannot get the datum id") } datumType, ok := bsonData["type"].(string) if !ok { - return datumID, nil, errors.New("cannot get the datum type") + return datumID, nil, errorsP.New("cannot get the datum type") } // TODO: based on discussions we want to ensure that these are the correct type From 5605634b0b4c2d8b585b1c55da4312f9f7713563 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 30 Jan 2024 17:25:23 +1300 Subject: [PATCH 146/413] skip parser errors for now --- migrations/20231128_jellyfish_migration/utils/utils.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index e5228abe8a..2c59939061 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -156,9 +156,9 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { parser.NotParsed() - if err := parser.Error(); err != nil { - parseErr = errors.Join(parseErr, err) - } + // if err := parser.Error(); err != nil { + // parseErr = errors.Join(parseErr, err) + // } if err := validator.Error(); err != nil { parseErr = errors.Join(parseErr, err) From b8b410e708e377e0e067719b892897375b75541c Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 30 Jan 2024 18:18:08 +1300 Subject: [PATCH 147/413] log just success for datums --- .../utils/utils.go | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 2c59939061..86bd057ae5 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -1,9 +1,7 @@ package utils import ( - "bytes" "encoding/json" - "errors" "fmt" "log" "os" @@ -84,10 +82,11 @@ func logUpdates(updatesJSON []byte) { os.Exit(1) } defer f.Close() - buf := &bytes.Buffer{} - if err := json.Indent(buf, updatesJSON, "", "\t"); err == nil { - f.WriteString(fmt.Sprintf("%s \n", buf.String())) - } + f.WriteString(fmt.Sprintf("%s \n", string(updatesJSON))) + // buf := &bytes.Buffer{} + // if err := json.Indent(buf, updatesJSON, "", "\t"); err == nil { + // f.WriteString(fmt.Sprintf("%s \n", buf.String())) + // } } func ProcessDatum(bsonData bson.M) (data.Datum, error) { @@ -129,14 +128,10 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { //marshal to json pretty print as source of comparison incomingJSONData, err := json.Marshal(bsonData) - - logUpdates(incomingJSONData) - if err != nil { return nil, err } ojbData := map[string]interface{}{} - if err := json.Unmarshal(incomingJSONData, &ojbData); err != nil { return nil, err } @@ -145,7 +140,6 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { validator := structureValidator.New() normalizer := dataNormalizer.New() - var parseErr error datum := dataTypesFactory.ParseDatum(parser) if datum != nil && *datum != nil { (*datum).Validate(validator) @@ -156,23 +150,19 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { parser.NotParsed() + // TODO lots of `ErrorNotParsed` exceptions // if err := parser.Error(); err != nil { // parseErr = errors.Join(parseErr, err) // } if err := validator.Error(); err != nil { - parseErr = errors.Join(parseErr, err) + return nil, err } if err := normalizer.Error(); err != nil { - parseErr = errors.Join(parseErr, err) - } - - if parseErr != nil { - return nil, parseErr + return nil, err } - // compare JSON before and after ... outgoingJSONData, err := json.Marshal(datum) if err != nil { return nil, err From 39b955836c2b9bc900015a880eb6e96234658c3f Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jan 2024 09:20:04 +1300 Subject: [PATCH 148/413] try adding diff --- go.mod | 1 + go.sum | 3 + .../jellyfish_migration.go | 2 +- .../utils/utils.go | 20 +- vendor/github.com/r3labs/diff/v3/.gitignore | 17 + .../github.com/r3labs/diff/v3/CONTRIBUTING.md | 80 ++++ vendor/github.com/r3labs/diff/v3/LICENSE | 373 ++++++++++++++++ vendor/github.com/r3labs/diff/v3/Makefile | 11 + vendor/github.com/r3labs/diff/v3/README.md | 327 ++++++++++++++ .../github.com/r3labs/diff/v3/change_value.go | 209 +++++++++ .../github.com/r3labs/diff/v3/comparative.go | 44 ++ vendor/github.com/r3labs/diff/v3/diff.go | 417 ++++++++++++++++++ vendor/github.com/r3labs/diff/v3/diff_bool.go | 29 ++ .../r3labs/diff/v3/diff_comparative.go | 62 +++ .../github.com/r3labs/diff/v3/diff_float.go | 35 ++ vendor/github.com/r3labs/diff/v3/diff_int.go | 35 ++ .../r3labs/diff/v3/diff_interface.go | 39 ++ vendor/github.com/r3labs/diff/v3/diff_map.go | 81 ++++ .../github.com/r3labs/diff/v3/diff_pointer.go | 60 +++ .../github.com/r3labs/diff/v3/diff_slice.go | 141 ++++++ .../github.com/r3labs/diff/v3/diff_string.go | 34 ++ .../github.com/r3labs/diff/v3/diff_struct.go | 123 ++++++ vendor/github.com/r3labs/diff/v3/diff_time.go | 36 ++ vendor/github.com/r3labs/diff/v3/diff_uint.go | 35 ++ vendor/github.com/r3labs/diff/v3/error.go | 74 ++++ vendor/github.com/r3labs/diff/v3/filter.go | 22 + vendor/github.com/r3labs/diff/v3/options.go | 93 ++++ vendor/github.com/r3labs/diff/v3/patch.go | 237 ++++++++++ vendor/github.com/r3labs/diff/v3/patch_map.go | 106 +++++ .../github.com/r3labs/diff/v3/patch_slice.go | 78 ++++ .../github.com/r3labs/diff/v3/patch_struct.go | 66 +++ vendor/modules.txt | 3 + 32 files changed, 2888 insertions(+), 5 deletions(-) create mode 100644 vendor/github.com/r3labs/diff/v3/.gitignore create mode 100644 vendor/github.com/r3labs/diff/v3/CONTRIBUTING.md create mode 100644 vendor/github.com/r3labs/diff/v3/LICENSE create mode 100644 vendor/github.com/r3labs/diff/v3/Makefile create mode 100644 vendor/github.com/r3labs/diff/v3/README.md create mode 100644 vendor/github.com/r3labs/diff/v3/change_value.go create mode 100644 vendor/github.com/r3labs/diff/v3/comparative.go create mode 100644 vendor/github.com/r3labs/diff/v3/diff.go create mode 100644 vendor/github.com/r3labs/diff/v3/diff_bool.go create mode 100644 vendor/github.com/r3labs/diff/v3/diff_comparative.go create mode 100644 vendor/github.com/r3labs/diff/v3/diff_float.go create mode 100644 vendor/github.com/r3labs/diff/v3/diff_int.go create mode 100644 vendor/github.com/r3labs/diff/v3/diff_interface.go create mode 100644 vendor/github.com/r3labs/diff/v3/diff_map.go create mode 100644 vendor/github.com/r3labs/diff/v3/diff_pointer.go create mode 100644 vendor/github.com/r3labs/diff/v3/diff_slice.go create mode 100644 vendor/github.com/r3labs/diff/v3/diff_string.go create mode 100644 vendor/github.com/r3labs/diff/v3/diff_struct.go create mode 100644 vendor/github.com/r3labs/diff/v3/diff_time.go create mode 100644 vendor/github.com/r3labs/diff/v3/diff_uint.go create mode 100644 vendor/github.com/r3labs/diff/v3/error.go create mode 100644 vendor/github.com/r3labs/diff/v3/filter.go create mode 100644 vendor/github.com/r3labs/diff/v3/options.go create mode 100644 vendor/github.com/r3labs/diff/v3/patch.go create mode 100644 vendor/github.com/r3labs/diff/v3/patch_map.go create mode 100644 vendor/github.com/r3labs/diff/v3/patch_slice.go create mode 100644 vendor/github.com/r3labs/diff/v3/patch_struct.go diff --git a/go.mod b/go.mod index 474c598260..d883e8473d 100644 --- a/go.mod +++ b/go.mod @@ -123,6 +123,7 @@ require ( github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.45.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect + github.com/r3labs/diff/v3 v3.0.1 // indirect github.com/radovskyb/watcher v1.0.7 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/go.sum b/go.sum index 0da3073d25..66c55d4a38 100644 --- a/go.sum +++ b/go.sum @@ -267,6 +267,8 @@ github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lne github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/r3labs/diff/v3 v3.0.1 h1:CBKqf3XmNRHXKmdU7mZP1w7TV0pDyVCis1AUHtA4Xtg= +github.com/r3labs/diff/v3 v3.0.1/go.mod h1:f1S9bourRbiM66NskseyUdo0fTmEE0qKrikYJX63dgo= github.com/radovskyb/watcher v1.0.7 h1:AYePLih6dpmS32vlHfhCeli8127LzkIgwJGcwwe8tUE= github.com/radovskyb/watcher v1.0.7/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm+ZuvsUYIg= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= @@ -326,6 +328,7 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index bfa0ada0b4..b881ecb861 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -321,7 +321,7 @@ func (m *Migration) fetchAndProcess() bool { if err != nil { m.migrationUtil.OnError(err, fmt.Sprintf("%v", item["_id"]), fmt.Sprintf("type [%v]", item["type"])) } - + all = append(all, item) } m.migrationUtil.SetFetched(all) return len(all) > 0 diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 86bd057ae5..b390296014 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -8,6 +8,7 @@ import ( "slices" "strings" + "github.com/r3labs/diff/v3" "go.mongodb.org/mongo-driver/bson" "github.com/tidepool-org/platform/data" @@ -74,7 +75,7 @@ func pumpSettingsHasBolus(bsonData bson.M) bool { return false } -func logUpdates(updatesJSON []byte) { +func logUpdates(id string, updates interface{}) { f, err := os.OpenFile("update.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { @@ -82,7 +83,7 @@ func logUpdates(updatesJSON []byte) { os.Exit(1) } defer f.Close() - f.WriteString(fmt.Sprintf("%s \n", string(updatesJSON))) + f.WriteString(fmt.Sprintf("%s %v \n", id, updates)) // buf := &bytes.Buffer{} // if err := json.Indent(buf, updatesJSON, "", "\t"); err == nil { // f.WriteString(fmt.Sprintf("%s \n", buf.String())) @@ -168,9 +169,20 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { return nil, err } - if string(incomingJSONData) != string(outgoingJSONData) { - logUpdates(outgoingJSONData) + processedData := map[string]interface{}{} + if err := json.Unmarshal(outgoingJSONData, &processedData); err != nil { + return nil, err } + + //get dif + changelog, _ := diff.Diff(ojbData, processedData) + logUpdates(fmt.Sprintf("%s", ojbData["_id"]), changelog) + + // log.Printf("changes %v", changelog) + + // if string(incomingJSONData) != string(outgoingJSONData) { + // logUpdates(outgoingJSONData) + // } return *datum, nil } diff --git a/vendor/github.com/r3labs/diff/v3/.gitignore b/vendor/github.com/r3labs/diff/v3/.gitignore new file mode 100644 index 0000000000..e04e61e4f9 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/.gitignore @@ -0,0 +1,17 @@ +# Binaries for programs and plugins +*.exe +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 +.glide/ +.idea/ + +patchflags_string.go diff --git a/vendor/github.com/r3labs/diff/v3/CONTRIBUTING.md b/vendor/github.com/r3labs/diff/v3/CONTRIBUTING.md new file mode 100644 index 0000000000..3c00b27c5e --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/CONTRIBUTING.md @@ -0,0 +1,80 @@ +# Contributing guidelines + +Looking to contribute something to this project? Here's how you can help: + +Please take a moment to review this document in order to make the contribution process easy and effective for everyone involved. + +Following these guidelines helps to communicate that you respect the time of the developers managing and developing this open source project. In return, they should reciprocate that respect in addressing your issue or assessing patches and features. + +We also have a [code of conduct](https://ernest.io/conduct). + +## Using the issue tracker + +The issue tracker is the preferred channel for [bug reports](#bug-reports), [features requests](#feature-requests) and [submitting pull requests](#pull-requests), but please respect the following restrictions: + +* Please **do not** use the issue tracker for personal support requests. + +* Please **do not** derail issues. Keep the discussion on topic and + respect the opinions of others. + + +## Bug reports + +A bug is a _demonstrable problem_ that is caused by the code in the repository. +Good bug reports are extremely helpful - thank you! + +Guidelines for bug reports: + +1. **Use the GitHub issue search** — check if the issue has already been + reported. + +2. **Check if the issue has been fixed** — try to reproduce it using the + latest `master` or `develop` branch in the repository. + +3. **Isolate the problem** — create a reduced test case and a live example. + +A good bug report shouldn't leave others needing to chase you up for more +information. Please try to be as detailed as possible in your report. What is +your environment? What steps will reproduce the issue? Which environment experience the problem? What would you expect to be the outcome? All these +details will help people to fix any potential bugs. + +Example: + +> Short and descriptive example bug report title +> +> A summary of the issue and the environment in which it occurs. If +> suitable, include the steps required to reproduce the bug. +> +> 1. This is the first step +> 2. This is the second step +> 3. Further steps, etc. +> +> `` - a link to the reduced test case +> +> Any other information you want to share that is relevant to the issue being +> reported. This might include the lines of code that you have identified as +> causing the bug, and potential solutions (and your opinions on their +> merits). + + +## Feature requests + +Feature requests are welcome. But take a moment to find out whether your idea +fits with the scope and aims of the project. It's up to *you* to make a strong +case to convince the project's developers of the merits of this feature. Please +provide as much detail and context as possible. + + +## Pull requests + +Good pull requests - patches, improvements, new features - are a fantastic +help. They should remain focused in scope and avoid containing unrelated +commits. + +[**Please ask first**](https://ernest.io/community) before embarking on any significant pull request (e.g. +implementing features, refactoring code, porting to a different language), +otherwise you risk spending a lot of time working on something that the +project's developers might not want to merge into the project. + +Please adhere to the coding conventions used throughout a project (indentation, +accurate comments, etc.) and any other requirements (such as test coverage). diff --git a/vendor/github.com/r3labs/diff/v3/LICENSE b/vendor/github.com/r3labs/diff/v3/LICENSE new file mode 100644 index 0000000000..a612ad9813 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/LICENSE @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/vendor/github.com/r3labs/diff/v3/Makefile b/vendor/github.com/r3labs/diff/v3/Makefile new file mode 100644 index 0000000000..f119f8c1e0 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/Makefile @@ -0,0 +1,11 @@ +install: + go install -v ${LDFLAGS} + +deps: + go get github.com/stretchr/testify + +test: + @go test -v -cover ./... + +cover: + @go test -coverprofile cover.out diff --git a/vendor/github.com/r3labs/diff/v3/README.md b/vendor/github.com/r3labs/diff/v3/README.md new file mode 100644 index 0000000000..97aee65e79 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/README.md @@ -0,0 +1,327 @@ +# Diff [![PkgGoDev](https://pkg.go.dev/badge/github.com/r3labs/diff)](https://pkg.go.dev/github.com/r3labs/diff) [![Go Report Card](https://goreportcard.com/badge/github.com/r3labs/diff)](https://goreportcard.com/report/github.com/r3labs/diff) [![Build Status](https://travis-ci.com/r3labs/diff.svg?branch=master)](https://travis-ci.com/r3labs/diff) + +A library for diffing golang structures and values. + +Utilizing field tags and reflection, it is able to compare two structures of the same type and create a changelog of all modified values. The produced changelog can easily be serialized to json. + +NOTE: All active development now takes place on the v3 branch. + +## Installation + +For version 3: +``` +go get github.com/r3labs/diff/v3 +``` + +## Changelog Format + +When diffing two structures using `Diff`, a changelog will be produced. Any detected changes will populate the changelog array with a Change type: + +```go +type Change struct { + Type string // The type of change detected; can be one of create, update or delete + Path []string // The path of the detected change; will contain any field name or array index that was part of the traversal + From interface{} // The original value that was present in the "from" structure + To interface{} // The new value that was detected as a change in the "to" structure +} +``` + +Given the example below, we are diffing two slices where the third element has been removed: + +```go +from := []int{1, 2, 3, 4} +to := []int{1, 2, 4} + +changelog, _ := diff.Diff(from, to) +``` + +The resultant changelog should contain one change: + +```go +Change{ + Type: "delete", + Path: ["2"], + From: 3, + To: nil, +} +``` + +## Supported Types + +A diffable value can be/contain any of the following types: + + +| Type | Supported | +| ------------ | --------- | +| struct | ✔ | +| slice | ✔ | +| string | ✔ | +| int | ✔ | +| bool | ✔ | +| map | ✔ | +| pointer | ✔ | +| custom types | ✔ | + + +Please see the docs for more supported types, options and features. + +### Tags + +In order for struct fields to be compared, they must be tagged with a given name. All tag values are prefixed with `diff`. i.e. `diff:"items"`. + +| Tag | Usage | +| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `-` | Excludes a value from being diffed | +| `identifier` | If you need to compare arrays by a matching identifier and not based on order, you can specify the `identifier` tag. If an identifiable element is found in both the from and to structures, they will be directly compared. i.e. `diff:"name, identifier"` | +| `immutable` | Will omit this struct field from diffing. When using `diff.StructValues()` these values will be added to the returned changelog. It's use case is for when we have nothing to compare a struct to and want to show all of its relevant values. | +| `nocreate` | The default patch action is to allocate instances in the target strut, map or slice should they not exist. Adding this flag will tell patch to skip elements that it would otherwise need to allocate. This is separate from immutable, which is also honored while patching. | +| `omitunequal` | Patching is a 'best effort' operation, and will by default attempt to update the 'correct' member of the target even if the underlying value has already changed to something other than the value in the change log 'from'. This tag will selectively ignore values that are not a 100% match. | + +## Usage + +### Basic Example + +Diffing a basic set of values can be accomplished using the diff functions. Any items that specify a "diff" tag using a name will be compared. + +```go +import "github.com/r3labs/diff/v3" + +type Order struct { + ID string `diff:"id"` + Items []int `diff:"items"` +} + +func main() { + a := Order{ + ID: "1234", + Items: []int{1, 2, 3, 4}, + } + + b := Order{ + ID: "1234", + Items: []int{1, 2, 4}, + } + + changelog, err := diff.Diff(a, b) + ... +} +``` + +In this example, the output generated in the changelog will indicate that the third element with a value of '3' was removed from items. +When marshalling the changelog to json, the output will look like: + +```json +[ + { + "type": "delete", + "path": ["items", "2"], + "from": 3, + "to": null + } +] +``` + +### Options and Configuration + +Options can be set on the differ at call time which effect how diff acts when building the change log. +```go +import "github.com/r3labs/diff/v3" + +type Order struct { + ID string `diff:"id"` + Items []int `diff:"items"` +} + +func main() { + a := Order{ + ID: "1234", + Items: []int{1, 2, 3, 4}, + } + + b := Order{ + ID: "1234", + Items: []int{1, 2, 4}, + } + + changelog, err := diff.Diff(a, b, diff.DisableStructValues(), diff.AllowTypeMismatch(true)) + ... +} +``` + +You can also create a new instance of a differ that allows options to be set. + +```go +import "github.com/r3labs/diff/v3" + +type Order struct { + ID string `diff:"id"` + Items []int `diff:"items"` +} + +func main() { + a := Order{ + ID: "1234", + Items: []int{1, 2, 3, 4}, + } + + b := Order{ + ID: "1234", + Items: []int{1, 2, 4}, + } + + d, err := diff.NewDiffer(diff.SliceOrdering(true)) + if err != nil { + panic(err) + } + + changelog, err := d.Diff(a, b) + ... +} +``` + +Supported options are: + +`SliceOrdering` ensures that the ordering of items in a slice is taken into account + +`DiscardComplexOrigin` is a directive to diff to omit additional origin information about structs. This alters the behavior of patch and can lead to some pitfalls and non-intuitive behavior if used. On the other hand, it can significantly reduce the memory footprint of large complex diffs. + +`AllowTypeMismatch` is a global directive to either allow (true) or not to allow (false) patch apply the changes if 'from' is not equal. This is effectively a global version of the omitunequal tag. + +`Filter` provides a callback that allows you to determine which fields the differ descends into + +`DisableStructValues` disables populating a separate change for each item in a struct, where the struct is being compared to a nil Value. + +`TagName` sets the tag name to use when getting field names and options. + +### Patch and merge support +Diff additionally supports merge and patch. Similar in concept to text patching / merging the Patch function, given +a change log and a target instance will make a _best effort_ to apply the changes in the change log to the variable +pointed to. The intention is that the target pointer is of the same type however, that doesn't necessarily have to be +true. For example, two slices of differing structs may be similar enough to apply changes to in a polymorphic way, and +patch will certainly try. + +The patch function doesn't actually fail, and even if there are errors, it may succeed sufficiently for the task at hand. +To accommodate this patch keeps track of each change log option it attempts to apply and reports the details of what +happened for further scrutiny. + +```go +import "github.com/r3labs/diff/v3" + +type Order struct { + ID string `diff:"id"` + Items []int `diff:"items"` +} + +func main() { + a := Order{ + ID: "1234", + Items: []int{1, 2, 3, 4}, + } + + b := Order{ + ID: "1234", + Items: []int{1, 2, 4}, + } + + c := Order{} + changelog, err := diff.Diff(a, b) + + patchlog := diff.Patch(changelog, &c) + //Note the lack of an error. Patch is best effort and uses flags to indicate actions taken + //and keeps any errors encountered along the way for review + fmt.Printf("Encountered %d errors while patching", patchlog.ErrorCount()) + ... +} +``` + +Instances of differ with options set can also be used when patching. + +```go +package main + +import "github.com/r3labs/diff/v3" + +type Order struct { + ID string `json:"id"` + Items []int `json:"items"` +} + +func main() { + a := Order{ + ID: "1234", + Items: []int{1, 2, 3, 4}, + } + + b := Order{ + ID: "1234", + Items: []int{1, 2, 4}, + } + + d, _ := diff.NewDiffer(diff.TagName("json")) + + changelog, _ := d.Diff(a, b) + + d.Patch(changelog, &a) + // reflect.DeepEqual(a, b) == true +} + +``` + +As a convenience, there is a Merge function that allows one to take three interfaces and perform all the tasks at the same +time. + +```go +import "github.com/r3labs/diff/v3" + +type Order struct { + ID string `diff:"id"` + Items []int `diff:"items"` +} + +func main() { + a := Order{ + ID: "1234", + Items: []int{1, 2, 3, 4}, + } + + b := Order{ + ID: "1234", + Items: []int{1, 2, 4}, + } + + c := Order{} + patchlog, err := diff.Merge(a, b, &c) + if err != nil { + fmt.Printf("Error encountered while diffing a & b") + } + fmt.Printf("Encountered %d errors while patching", patchlog.ErrorCount()) + ... +} +``` +## Running Tests + +``` +make test +``` + +## Contributing + +Please read through our +[contributing guidelines](CONTRIBUTING.md). +Included are directions for opening issues, coding standards, and notes on +development. + +Moreover, if your pull request contains patches or features, you must include +relevant unit tests. + +## Versioning + +For transparency into our release cycle and in striving to maintain backward +compatibility, this project is maintained under [the Semantic Versioning guidelines](http://semver.org/). + +## Copyright and License + +Code and documentation copyright since 2015 r3labs.io authors. + +Code released under +[the Mozilla Public License Version 2.0](LICENSE). diff --git a/vendor/github.com/r3labs/diff/v3/change_value.go b/vendor/github.com/r3labs/diff/v3/change_value.go new file mode 100644 index 0000000000..b0f3a73802 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/change_value.go @@ -0,0 +1,209 @@ +package diff + +import ( + "fmt" + "reflect" +) + +//ChangeValue is a specialized struct for monitoring patching +type ChangeValue struct { + parent *reflect.Value + target *reflect.Value + flags PatchFlags + change *Change + err error + pos int + index int + key reflect.Value +} + +//swap swaps out the target as we move down the path. Note that a nil +// check is foregone here due to the fact we control usage. +func (c *ChangeValue) swap(newTarget *reflect.Value) { + if newTarget.IsValid() { + c.ClearFlag(FlagInvalidTarget) + c.parent = c.target + c.target = newTarget + c.pos++ + } +} + +// Sets a flag on the node and saves the change +func (c *ChangeValue) SetFlag(flag PatchFlags) { + if c != nil { + c.flags = c.flags | flag + } +} + +//ClearFlag removes just a single flag +func (c *ChangeValue) ClearFlag(flag PatchFlags) { + if c != nil { + c.flags = c.flags &^ flag + } +} + +//HasFlag indicates if a flag is set on the node. returns false if node is bad +func (c *ChangeValue) HasFlag(flag PatchFlags) bool { + return (c.flags & flag) != 0 +} + +//IsValid echo for is valid +func (c *ChangeValue) IsValid() bool { + if c != nil { + return c.target.IsValid() || !c.HasFlag(FlagInvalidTarget) + } + return false +} + +//ParentKind - helps keep us nil safe +func (c ChangeValue) ParentKind() reflect.Kind { + if c.parent != nil { + return c.parent.Kind() + } + return reflect.Invalid +} + +//ParentLen is a nil safe parent length check +func (c ChangeValue) ParentLen() (ret int) { + if c.parent != nil && + (c.parent.Kind() == reflect.Slice || + c.parent.Kind() == reflect.Map) { + ret = c.parent.Len() + } + return +} + +//ParentSet - nil safe parent set +func (c *ChangeValue) ParentSet(value reflect.Value, convertCompatibleTypes bool) { + if c != nil && c.parent != nil { + defer func() { + if r := recover(); r != nil { + c.SetFlag(FlagParentSetFailed) + } + }() + + if convertCompatibleTypes { + if !value.Type().ConvertibleTo(c.parent.Type()) { + c.AddError(fmt.Errorf("Value of type %s is not convertible to %s", value.Type().String(), c.parent.Type().String())) + c.SetFlag(FlagParentSetFailed) + return + } + c.parent.Set(value.Convert(c.parent.Type())) + } else { + c.parent.Set(value) + } + c.SetFlag(FlagParentSetApplied) + } +} + +//Len echo for len +func (c ChangeValue) Len() int { + return c.target.Len() +} + +//Set echos reflect set +func (c *ChangeValue) Set(value reflect.Value, convertCompatibleTypes bool) { + if c == nil { + return + } + + defer func() { + if r := recover(); r != nil { + switch e := r.(type) { + case string: + c.AddError(NewError(e)) + case *reflect.ValueError: + c.AddError(NewError(e.Error())) + } + + c.SetFlag(FlagFailed) + } + }() + + if c.HasFlag(OptionImmutable) { + c.SetFlag(FlagIgnored) + return + } + + if convertCompatibleTypes { + if c.target.Kind() == reflect.Ptr && value.Kind() != reflect.Ptr { + if !value.IsValid() { + c.target.Set(reflect.Zero(c.target.Type())) + c.SetFlag(FlagApplied) + return + } else if !value.Type().ConvertibleTo(c.target.Elem().Type()) { + c.AddError(fmt.Errorf("Value of type %s is not convertible to %s", value.Type().String(), c.target.Type().String())) + c.SetFlag(FlagFailed) + return + } + + tv := reflect.New(c.target.Elem().Type()) + tv.Elem().Set(value.Convert(c.target.Elem().Type())) + c.target.Set(tv) + } else { + if !value.Type().ConvertibleTo(c.target.Type()) { + c.AddError(fmt.Errorf("Value of type %s is not convertible to %s", value.Type().String(), c.target.Type().String())) + c.SetFlag(FlagFailed) + return + } + + c.target.Set(value.Convert(c.target.Type())) + } + } else { + if value.IsValid() { + if c.target.Kind() == reflect.Ptr && value.Kind() != reflect.Ptr { + tv := reflect.New(value.Type()) + tv.Elem().Set(value) + c.target.Set(tv) + } else { + c.target.Set(value) + } + } else if c.target.Kind() == reflect.Ptr { + c.target.Set(reflect.Zero(c.target.Type())) + } else if !c.target.IsZero() { + t := c.target.Elem() + t.Set(reflect.Zero(t.Type())) + } + } + c.SetFlag(FlagApplied) +} + +//Index echo for index +func (c ChangeValue) Index(i int) reflect.Value { + return c.target.Index(i) +} + +//ParentIndex - get us the parent version, nil safe +func (c ChangeValue) ParentIndex(i int) (ret reflect.Value) { + if c.parent != nil { + ret = c.parent.Index(i) + } + return +} + +//Instance a new element of type for target. Taking the +//copy of the complex origin avoids the 'lack of data' issue +//present when allocating complex structs with slices and +//arrays +func (c ChangeValue) NewElement() reflect.Value { + ret := c.change.parent + if ret != nil { + return reflect.ValueOf(ret) + } + return reflect.New(c.target.Type().Elem()).Elem() +} + +//NewArrayElement gives us a dynamically typed new element +func (c ChangeValue) NewArrayElement() reflect.Value { + c.target.Set(reflect.Append(*c.target, c.NewElement())) + c.SetFlag(FlagCreated) + return c.Index(c.Len() - 1) +} + +//AddError appends errors to this change value +func (c *ChangeValue) AddError(err error) *ChangeValue { + if c != nil { + c.err = err + } + return c +} diff --git a/vendor/github.com/r3labs/diff/v3/comparative.go b/vendor/github.com/r3labs/diff/v3/comparative.go new file mode 100644 index 0000000000..f92ff6bdd2 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/comparative.go @@ -0,0 +1,44 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package diff + +import ( + "reflect" +) + +// Comparative ... +type Comparative struct { + A, B *reflect.Value +} + +// ComparativeList : stores indexed comparative +type ComparativeList struct { + m map[interface{}]*Comparative + keys []interface{} +} + +// NewComparativeList : returns a new comparative list +func NewComparativeList() *ComparativeList { + return &ComparativeList{ + m: make(map[interface{}]*Comparative), + keys: make([]interface{}, 0), + } +} + +func (cl *ComparativeList) addA(k interface{}, v *reflect.Value) { + if (*cl).m[k] == nil { + (*cl).m[k] = &Comparative{} + (*cl).keys = append((*cl).keys, k) + } + (*cl).m[k].A = v +} + +func (cl *ComparativeList) addB(k interface{}, v *reflect.Value) { + if (*cl).m[k] == nil { + (*cl).m[k] = &Comparative{} + (*cl).keys = append((*cl).keys, k) + } + (*cl).m[k].B = v +} diff --git a/vendor/github.com/r3labs/diff/v3/diff.go b/vendor/github.com/r3labs/diff/v3/diff.go new file mode 100644 index 0000000000..3c2ba17663 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/diff.go @@ -0,0 +1,417 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package diff + +import ( + "errors" + "fmt" + "reflect" + "strconv" + "strings" + + "github.com/vmihailenco/msgpack/v5" +) + +const ( + // CREATE represents when an element has been added + CREATE = "create" + // UPDATE represents when an element has been updated + UPDATE = "update" + // DELETE represents when an element has been removed + DELETE = "delete" +) + +// DiffType represents an enum with all the supported diff types +type DiffType uint8 + +const ( + UNSUPPORTED DiffType = iota + STRUCT + SLICE + ARRAY + STRING + BOOL + INT + UINT + FLOAT + MAP + PTR + INTERFACE +) + +func (t DiffType) String() string { + switch t { + case STRUCT: + return "STRUCT" + case SLICE: + return "SLICE" + case ARRAY: + return "ARRAY" + case STRING: + return "STRING" + case BOOL: + return "BOOL" + case INT: + return "INT" + case UINT: + return "UINT" + case FLOAT: + return "FLOAT" + case MAP: + return "MAP" + case PTR: + return "PTR" + case INTERFACE: + return "INTERFACE" + default: + return "UNSUPPORTED" + } +} + +// DiffFunc represents the built-in diff functions +type DiffFunc func([]string, reflect.Value, reflect.Value, interface{}) error + +// Differ a configurable diff instance +type Differ struct { + TagName string + SliceOrdering bool + DisableStructValues bool + customValueDiffers []ValueDiffer + cl Changelog + AllowTypeMismatch bool + DiscardParent bool + StructMapKeys bool + FlattenEmbeddedStructs bool + ConvertCompatibleTypes bool + Filter FilterFunc +} + +// Changelog stores a list of changed items +type Changelog []Change + +// Change stores information about a changed item +type Change struct { + Type string `json:"type"` + Path []string `json:"path"` + From interface{} `json:"from"` + To interface{} `json:"to"` + parent interface{} `json:"parent"` +} + +// ValueDiffer is an interface for custom differs +type ValueDiffer interface { + Match(a, b reflect.Value) bool + Diff(dt DiffType, df DiffFunc, cl *Changelog, path []string, a, b reflect.Value, parent interface{}) error + InsertParentDiffer(dfunc func(path []string, a, b reflect.Value, p interface{}) error) +} + +// Changed returns true if both values differ +func Changed(a, b interface{}) bool { + cl, _ := Diff(a, b) + return len(cl) > 0 +} + +// Diff returns a changelog of all mutated values from both +func Diff(a, b interface{}, opts ...func(d *Differ) error) (Changelog, error) { + d, err := NewDiffer(opts...) + if err != nil { + return nil, err + } + return d.Diff(a, b) +} + +// NewDiffer creates a new configurable diffing object +func NewDiffer(opts ...func(d *Differ) error) (*Differ, error) { + d := Differ{ + TagName: "diff", + DiscardParent: false, + } + + for _, opt := range opts { + err := opt(&d) + if err != nil { + return nil, err + } + } + + return &d, nil +} + +// FilterFunc is a function that determines whether to descend into a struct field. +// parent is the struct being examined and field is a field on that struct. path +// is the path to the field from the root of the diff. +type FilterFunc func(path []string, parent reflect.Type, field reflect.StructField) bool + +// StructValues gets all values from a struct +// values are stored as "created" or "deleted" entries in the changelog, +// depending on the change type specified +func StructValues(t string, path []string, s interface{}) (Changelog, error) { + d := Differ{ + TagName: "diff", + DiscardParent: false, + } + + v := reflect.ValueOf(s) + + return d.cl, d.structValues(t, path, v) +} + +// FilterOut filter out the changes based on path. Paths may contain valid regexp to match items +func (cl *Changelog) FilterOut(path []string) Changelog { + var ncl Changelog + + for _, c := range *cl { + if !pathmatch(path, c.Path) { + ncl = append(ncl, c) + } + } + + return ncl +} + +// Filter filter changes based on path. Paths may contain valid regexp to match items +func (cl *Changelog) Filter(path []string) Changelog { + var ncl Changelog + + for _, c := range *cl { + if pathmatch(path, c.Path) { + ncl = append(ncl, c) + } + } + + return ncl +} + +func (d *Differ) getDiffType(a, b reflect.Value) (DiffType, DiffFunc) { + switch { + case are(a, b, reflect.Struct, reflect.Invalid): + return STRUCT, d.diffStruct + case are(a, b, reflect.Slice, reflect.Invalid): + return SLICE, d.diffSlice + case are(a, b, reflect.Array, reflect.Invalid): + return ARRAY, d.diffSlice + case are(a, b, reflect.String, reflect.Invalid): + return STRING, d.diffString + case are(a, b, reflect.Bool, reflect.Invalid): + return BOOL, d.diffBool + case are(a, b, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Invalid): + return INT, d.diffInt + case are(a, b, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Invalid): + return UINT, d.diffUint + case are(a, b, reflect.Float32, reflect.Float64, reflect.Invalid): + return FLOAT, d.diffFloat + case are(a, b, reflect.Map, reflect.Invalid): + return MAP, d.diffMap + case are(a, b, reflect.Ptr, reflect.Invalid): + return PTR, d.diffPtr + case are(a, b, reflect.Interface, reflect.Invalid): + return INTERFACE, d.diffInterface + default: + return UNSUPPORTED, nil + } +} + +// Diff returns a changelog of all mutated values from both +func (d *Differ) Diff(a, b interface{}) (Changelog, error) { + // reset the state of the diff + d.cl = Changelog{} + + return d.cl, d.diff([]string{}, reflect.ValueOf(a), reflect.ValueOf(b), nil) +} + +func (d *Differ) diff(path []string, a, b reflect.Value, parent interface{}) error { + + //look and see if we need to discard the parent + if parent != nil { + if d.DiscardParent || reflect.TypeOf(parent).Kind() != reflect.Struct { + parent = nil + } + } + + // check if types match or are + if invalid(a, b) { + if d.AllowTypeMismatch { + d.cl.Add(UPDATE, path, a.Interface(), b.Interface()) + return nil + } + return ErrTypeMismatch + } + + // get the diff type and the corresponding built-int diff function to handle this type + diffType, diffFunc := d.getDiffType(a, b) + + // first go through custom diff functions + if len(d.customValueDiffers) > 0 { + for _, vd := range d.customValueDiffers { + if vd.Match(a, b) { + err := vd.Diff(diffType, diffFunc, &d.cl, path, a, b, parent) + if err != nil { + return err + } + return nil + } + } + } + + // then built-in diff functions + if diffType == UNSUPPORTED { + return errors.New("unsupported type: " + a.Kind().String()) + } + + return diffFunc(path, a, b, parent) +} + +func (cl *Changelog) Add(t string, path []string, ftco ...interface{}) { + change := Change{ + Type: t, + Path: path, + From: ftco[0], + To: ftco[1], + } + if len(ftco) > 2 { + change.parent = ftco[2] + } + (*cl) = append((*cl), change) +} + +func tagName(tag string, f reflect.StructField) string { + t := f.Tag.Get(tag) + + parts := strings.Split(t, ",") + if len(parts) < 1 { + return "-" + } + + return parts[0] +} + +func identifier(tag string, v reflect.Value) interface{} { + if v.Kind() != reflect.Struct { + return nil + } + + for i := 0; i < v.NumField(); i++ { + if hasTagOption(tag, v.Type().Field(i), "identifier") { + return v.Field(i).Interface() + } + } + + return nil +} + +func hasTagOption(tag string, f reflect.StructField, opt string) bool { + parts := strings.Split(f.Tag.Get(tag), ",") + if len(parts) < 2 { + return false + } + + for _, option := range parts[1:] { + if option == opt { + return true + } + } + + return false +} + +func swapChange(t string, c Change) Change { + nc := Change{ + Type: t, + Path: c.Path, + } + + switch t { + case CREATE: + nc.To = c.To + case DELETE: + nc.From = c.To + } + + return nc +} + +func idComplex(v interface{}) string { + switch v := v.(type) { + case string: + return v + case int: + return strconv.Itoa(v) + default: + b, err := msgpack.Marshal(v) + if err != nil { + panic(err) + } + return string(b) + } + +} +func idstring(v interface{}) string { + switch v := v.(type) { + case string: + return v + case int: + return strconv.Itoa(v) + default: + return fmt.Sprint(v) + } +} + +func invalid(a, b reflect.Value) bool { + if a.Kind() == b.Kind() { + return false + } + + if a.Kind() == reflect.Invalid { + return false + } + if b.Kind() == reflect.Invalid { + return false + } + + return true +} + +func are(a, b reflect.Value, kinds ...reflect.Kind) bool { + var amatch, bmatch bool + + for _, k := range kinds { + if a.Kind() == k { + amatch = true + } + if b.Kind() == k { + bmatch = true + } + } + + return amatch && bmatch +} + +func AreType(a, b reflect.Value, types ...reflect.Type) bool { + var amatch, bmatch bool + + for _, t := range types { + if a.Kind() != reflect.Invalid { + if a.Type() == t { + amatch = true + } + } + if b.Kind() != reflect.Invalid { + if b.Type() == t { + bmatch = true + } + } + } + + return amatch && bmatch +} + +func copyAppend(src []string, elems ...string) []string { + dst := make([]string, len(src)+len(elems)) + copy(dst, src) + for i := len(src); i < len(src)+len(elems); i++ { + dst[i] = elems[i-len(src)] + } + return dst +} diff --git a/vendor/github.com/r3labs/diff/v3/diff_bool.go b/vendor/github.com/r3labs/diff/v3/diff_bool.go new file mode 100644 index 0000000000..0e30503368 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/diff_bool.go @@ -0,0 +1,29 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package diff + +import "reflect" + +func (d *Differ) diffBool(path []string, a, b reflect.Value, parent interface{}) error { + if a.Kind() == reflect.Invalid { + d.cl.Add(CREATE, path, nil, exportInterface(b)) + return nil + } + + if b.Kind() == reflect.Invalid { + d.cl.Add(DELETE, path, exportInterface(a), nil) + return nil + } + + if a.Kind() != b.Kind() { + return ErrTypeMismatch + } + + if a.Bool() != b.Bool() { + d.cl.Add(UPDATE, path, exportInterface(a), exportInterface(b), parent) + } + + return nil +} diff --git a/vendor/github.com/r3labs/diff/v3/diff_comparative.go b/vendor/github.com/r3labs/diff/v3/diff_comparative.go new file mode 100644 index 0000000000..7359d17f5f --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/diff_comparative.go @@ -0,0 +1,62 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package diff + +import ( + "reflect" +) + +func (d *Differ) diffComparative(path []string, c *ComparativeList, parent interface{}) error { + for _, k := range c.keys { + id := idstring(k) + if d.StructMapKeys { + id = idComplex(k) + } + + fpath := copyAppend(path, id) + nv := reflect.ValueOf(nil) + + if c.m[k].A == nil { + c.m[k].A = &nv + } + + if c.m[k].B == nil { + c.m[k].B = &nv + } + + err := d.diff(fpath, *c.m[k].A, *c.m[k].B, parent) + if err != nil { + return err + } + } + + return nil +} + +func (d *Differ) comparative(a, b reflect.Value) bool { + if a.Len() > 0 { + ae := a.Index(0) + ak := getFinalValue(ae) + + if ak.Kind() == reflect.Struct { + if identifier(d.TagName, ak) != nil { + return true + } + } + } + + if b.Len() > 0 { + be := b.Index(0) + bk := getFinalValue(be) + + if bk.Kind() == reflect.Struct { + if identifier(d.TagName, bk) != nil { + return true + } + } + } + + return false +} diff --git a/vendor/github.com/r3labs/diff/v3/diff_float.go b/vendor/github.com/r3labs/diff/v3/diff_float.go new file mode 100644 index 0000000000..9494365e87 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/diff_float.go @@ -0,0 +1,35 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package diff + +import ( + "reflect" +) + +func (d *Differ) diffFloat(path []string, a, b reflect.Value, parent interface{}) error { + if a.Kind() == reflect.Invalid { + d.cl.Add(CREATE, path, nil, exportInterface(b)) + return nil + } + + if b.Kind() == reflect.Invalid { + d.cl.Add(DELETE, path, exportInterface(a), nil) + return nil + } + + if a.Kind() != b.Kind() { + return ErrTypeMismatch + } + + if a.Float() != b.Float() { + if a.CanInterface() { + d.cl.Add(UPDATE, path, exportInterface(a), exportInterface(b), parent) + } else { + d.cl.Add(UPDATE, path, a.Float(), b.Float(), parent) + } + } + + return nil +} diff --git a/vendor/github.com/r3labs/diff/v3/diff_int.go b/vendor/github.com/r3labs/diff/v3/diff_int.go new file mode 100644 index 0000000000..3658bf77ca --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/diff_int.go @@ -0,0 +1,35 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package diff + +import ( + "reflect" +) + +func (d *Differ) diffInt(path []string, a, b reflect.Value, parent interface{}) error { + if a.Kind() == reflect.Invalid { + d.cl.Add(CREATE, path, nil, exportInterface(b)) + return nil + } + + if b.Kind() == reflect.Invalid { + d.cl.Add(DELETE, path, exportInterface(a), nil) + return nil + } + + if a.Kind() != b.Kind() { + return ErrTypeMismatch + } + + if a.Int() != b.Int() { + if a.CanInterface() { + d.cl.Add(UPDATE, path, exportInterface(a), exportInterface(b), parent) + } else { + d.cl.Add(UPDATE, path, a.Int(), b.Int(), parent) + } + } + + return nil +} diff --git a/vendor/github.com/r3labs/diff/v3/diff_interface.go b/vendor/github.com/r3labs/diff/v3/diff_interface.go new file mode 100644 index 0000000000..ef6cde8771 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/diff_interface.go @@ -0,0 +1,39 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package diff + +import "reflect" + +func (d *Differ) diffInterface(path []string, a, b reflect.Value, parent interface{}) error { + if a.Kind() == reflect.Invalid { + d.cl.Add(CREATE, path, nil, exportInterface(b)) + return nil + } + + if b.Kind() == reflect.Invalid { + d.cl.Add(DELETE, path, exportInterface(a), nil) + return nil + } + + if a.Kind() != b.Kind() { + return ErrTypeMismatch + } + + if a.IsNil() && b.IsNil() { + return nil + } + + if a.IsNil() { + d.cl.Add(UPDATE, path, nil, exportInterface(b), parent) + return nil + } + + if b.IsNil() { + d.cl.Add(UPDATE, path, exportInterface(a), nil, parent) + return nil + } + + return d.diff(path, a.Elem(), b.Elem(), parent) +} diff --git a/vendor/github.com/r3labs/diff/v3/diff_map.go b/vendor/github.com/r3labs/diff/v3/diff_map.go new file mode 100644 index 0000000000..675ff931f2 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/diff_map.go @@ -0,0 +1,81 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package diff + +import ( + "fmt" + "reflect" + + "github.com/vmihailenco/msgpack/v5" +) + +func (d *Differ) diffMap(path []string, a, b reflect.Value, parent interface{}) error { + if a.Kind() == reflect.Invalid { + return d.mapValues(CREATE, path, b) + } + + if b.Kind() == reflect.Invalid { + return d.mapValues(DELETE, path, a) + } + + c := NewComparativeList() + + for _, k := range a.MapKeys() { + ae := a.MapIndex(k) + c.addA(exportInterface(k), &ae) + } + + for _, k := range b.MapKeys() { + be := b.MapIndex(k) + c.addB(exportInterface(k), &be) + } + + return d.diffComparative(path, c, exportInterface(a)) +} + +func (d *Differ) mapValues(t string, path []string, a reflect.Value) error { + if t != CREATE && t != DELETE { + return ErrInvalidChangeType + } + + if a.Kind() == reflect.Ptr { + a = reflect.Indirect(a) + } + + if a.Kind() != reflect.Map { + return ErrTypeMismatch + } + + x := reflect.New(a.Type()).Elem() + + for _, k := range a.MapKeys() { + ae := a.MapIndex(k) + xe := x.MapIndex(k) + + var err error + if d.StructMapKeys { + //it's not enough to turn k to a string, we need to able to marshal a type when + //we apply it in patch so... we'll marshal it to JSON + var b []byte + if b, err = msgpack.Marshal(k.Interface()); err == nil { + err = d.diff(append(path, string(b)), xe, ae, a.Interface()) + } + } else { + err = d.diff(append(path, fmt.Sprint(k.Interface())), xe, ae, a.Interface()) + } + if err != nil { + return err + } + } + + for i := 0; i < len(d.cl); i++ { + // only swap changes on the relevant map + if pathmatch(path, d.cl[i].Path) { + d.cl[i] = swapChange(t, d.cl[i]) + } + } + + return nil +} diff --git a/vendor/github.com/r3labs/diff/v3/diff_pointer.go b/vendor/github.com/r3labs/diff/v3/diff_pointer.go new file mode 100644 index 0000000000..7c9d875144 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/diff_pointer.go @@ -0,0 +1,60 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package diff + +import ( + "reflect" + "unsafe" +) + +var isExportFlag uintptr = (1 << 5) | (1 << 6) + +func (d *Differ) diffPtr(path []string, a, b reflect.Value, parent interface{}) error { + if a.Kind() != b.Kind() { + if a.Kind() == reflect.Invalid { + if !b.IsNil() { + return d.diff(path, reflect.ValueOf(nil), reflect.Indirect(b), parent) + } + + d.cl.Add(CREATE, path, nil, exportInterface(b), parent) + return nil + } + + if b.Kind() == reflect.Invalid { + if !a.IsNil() { + return d.diff(path, reflect.Indirect(a), reflect.ValueOf(nil), parent) + } + + d.cl.Add(DELETE, path, exportInterface(a), nil, parent) + return nil + } + + return ErrTypeMismatch + } + + if a.IsNil() && b.IsNil() { + return nil + } + + if a.IsNil() { + d.cl.Add(UPDATE, path, nil, exportInterface(b), parent) + return nil + } + + if b.IsNil() { + d.cl.Add(UPDATE, path, exportInterface(a), nil, parent) + return nil + } + + return d.diff(path, reflect.Indirect(a), reflect.Indirect(b), parent) +} + +func exportInterface(v reflect.Value) interface{} { + if !v.CanInterface() { + flagTmp := (*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + 2*unsafe.Sizeof(uintptr(0)))) + *flagTmp = (*flagTmp) & (^isExportFlag) + } + return v.Interface() +} diff --git a/vendor/github.com/r3labs/diff/v3/diff_slice.go b/vendor/github.com/r3labs/diff/v3/diff_slice.go new file mode 100644 index 0000000000..3fd281b991 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/diff_slice.go @@ -0,0 +1,141 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package diff + +import ( + "reflect" +) + +func (d *Differ) diffSlice(path []string, a, b reflect.Value, parent interface{}) error { + if a.Kind() == reflect.Invalid { + d.cl.Add(CREATE, path, nil, exportInterface(b)) + return nil + } + + if b.Kind() == reflect.Invalid { + d.cl.Add(DELETE, path, exportInterface(a), nil) + return nil + } + + if a.Kind() != b.Kind() { + return ErrTypeMismatch + } + + if d.comparative(a, b) { + return d.diffSliceComparative(path, a, b) + } + + return d.diffSliceGeneric(path, a, b) +} + +func (d *Differ) diffSliceGeneric(path []string, a, b reflect.Value) error { + missing := NewComparativeList() + + slice := sliceTracker{} + for i := 0; i < a.Len(); i++ { + ae := a.Index(i) + + if (d.SliceOrdering && !hasAtSameIndex(b, ae, i)) || (!d.SliceOrdering && !slice.has(b, ae, d)) { + missing.addA(i, &ae) + } + } + + slice = sliceTracker{} + for i := 0; i < b.Len(); i++ { + be := b.Index(i) + + if (d.SliceOrdering && !hasAtSameIndex(a, be, i)) || (!d.SliceOrdering && !slice.has(a, be, d)) { + missing.addB(i, &be) + } + } + + // fallback to comparing based on order in slice if item is missing + if len(missing.keys) == 0 { + return nil + } + + return d.diffComparative(path, missing, exportInterface(a)) +} + +func (d *Differ) diffSliceComparative(path []string, a, b reflect.Value) error { + c := NewComparativeList() + + for i := 0; i < a.Len(); i++ { + ae := a.Index(i) + ak := getFinalValue(ae) + + id := identifier(d.TagName, ak) + if id != nil { + c.addA(id, &ae) + } + } + + for i := 0; i < b.Len(); i++ { + be := b.Index(i) + bk := getFinalValue(be) + + id := identifier(d.TagName, bk) + if id != nil { + c.addB(id, &be) + } + } + + return d.diffComparative(path, c, exportInterface(a)) +} + +// keeps track of elements that have already been matched, to stop duplicate matches from occurring +type sliceTracker []bool + +func (st *sliceTracker) has(s, v reflect.Value, d *Differ) bool { + if len(*st) != s.Len() { + (*st) = make([]bool, s.Len()) + } + + for i := 0; i < s.Len(); i++ { + // skip already matched elements + if (*st)[i] { + continue + } + + x := s.Index(i) + + var nd Differ + nd.Filter = d.Filter + nd.customValueDiffers = d.customValueDiffers + + err := nd.diff([]string{}, x, v, nil) + if err != nil { + continue + } + + if len(nd.cl) == 0 { + (*st)[i] = true + return true + } + } + + return false +} + +func getFinalValue(t reflect.Value) reflect.Value { + switch t.Kind() { + case reflect.Interface: + return getFinalValue(t.Elem()) + case reflect.Ptr: + return getFinalValue(reflect.Indirect(t)) + default: + return t + } +} + +func hasAtSameIndex(s, v reflect.Value, atIndex int) bool { + // check the element in the slice at atIndex to see if it matches Value, if it is a valid index into the slice + if atIndex < s.Len() { + x := s.Index(atIndex) + return reflect.DeepEqual(exportInterface(x), exportInterface(v)) + } + + return false +} diff --git a/vendor/github.com/r3labs/diff/v3/diff_string.go b/vendor/github.com/r3labs/diff/v3/diff_string.go new file mode 100644 index 0000000000..74182e2fe4 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/diff_string.go @@ -0,0 +1,34 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package diff + +import "reflect" + +func (d *Differ) diffString(path []string, a, b reflect.Value, parent interface{}) error { + if a.Kind() == reflect.Invalid { + d.cl.Add(CREATE, path, nil, exportInterface(b)) + return nil + } + + if b.Kind() == reflect.Invalid { + d.cl.Add(DELETE, path, exportInterface(a), nil) + return nil + } + + if a.Kind() != b.Kind() { + return ErrTypeMismatch + } + + if a.String() != b.String() { + if a.CanInterface() { + // If a and/or b is of a type that is an alias for String, store that type in changelog + d.cl.Add(UPDATE, path, exportInterface(a), exportInterface(b), parent) + } else { + d.cl.Add(UPDATE, path, a.String(), b.String(), parent) + } + } + + return nil +} diff --git a/vendor/github.com/r3labs/diff/v3/diff_struct.go b/vendor/github.com/r3labs/diff/v3/diff_struct.go new file mode 100644 index 0000000000..fb14c57cce --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/diff_struct.go @@ -0,0 +1,123 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package diff + +import ( + "reflect" + "time" +) + +func (d *Differ) diffStruct(path []string, a, b reflect.Value, parent interface{}) error { + if AreType(a, b, reflect.TypeOf(time.Time{})) { + return d.diffTime(path, a, b) + } + + if a.Kind() == reflect.Invalid { + if d.DisableStructValues { + d.cl.Add(CREATE, path, nil, exportInterface(b)) + return nil + } + return d.structValues(CREATE, path, b) + } + + if b.Kind() == reflect.Invalid { + if d.DisableStructValues { + d.cl.Add(DELETE, path, exportInterface(a), nil) + return nil + } + return d.structValues(DELETE, path, a) + } + + for i := 0; i < a.NumField(); i++ { + field := a.Type().Field(i) + tname := tagName(d.TagName, field) + + if tname == "-" || hasTagOption(d.TagName, field, "immutable") { + continue + } + + if tname == "" { + tname = field.Name + } + + af := a.Field(i) + bf := b.FieldByName(field.Name) + + fpath := path + if !(d.FlattenEmbeddedStructs && field.Anonymous) { + fpath = copyAppend(fpath, tname) + } + + if d.Filter != nil && !d.Filter(fpath, a.Type(), field) { + continue + } + + // skip private fields + if !a.CanInterface() { + continue + } + + err := d.diff(fpath, af, bf, exportInterface(a)) + if err != nil { + return err + } + } + + return nil +} + +func (d *Differ) structValues(t string, path []string, a reflect.Value) error { + var nd Differ + nd.Filter = d.Filter + nd.customValueDiffers = d.customValueDiffers + + if t != CREATE && t != DELETE { + return ErrInvalidChangeType + } + + if a.Kind() == reflect.Ptr { + a = reflect.Indirect(a) + } + + if a.Kind() != reflect.Struct { + return ErrTypeMismatch + } + + x := reflect.New(a.Type()).Elem() + + for i := 0; i < a.NumField(); i++ { + + field := a.Type().Field(i) + tname := tagName(d.TagName, field) + + if tname == "-" { + continue + } + + if tname == "" { + tname = field.Name + } + + af := a.Field(i) + xf := x.FieldByName(field.Name) + + fpath := copyAppend(path, tname) + + if nd.Filter != nil && !nd.Filter(fpath, a.Type(), field) { + continue + } + + err := nd.diff(fpath, xf, af, exportInterface(a)) + if err != nil { + return err + } + } + + for i := 0; i < len(nd.cl); i++ { + (d.cl) = append(d.cl, swapChange(t, nd.cl[i])) + } + + return nil +} diff --git a/vendor/github.com/r3labs/diff/v3/diff_time.go b/vendor/github.com/r3labs/diff/v3/diff_time.go new file mode 100644 index 0000000000..4275e4aeaa --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/diff_time.go @@ -0,0 +1,36 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package diff + +import ( + "reflect" + "time" +) + +func (d *Differ) diffTime(path []string, a, b reflect.Value) error { + if a.Kind() == reflect.Invalid { + d.cl.Add(CREATE, path, nil, exportInterface(b)) + return nil + } + + if b.Kind() == reflect.Invalid { + d.cl.Add(DELETE, path, exportInterface(a), nil) + return nil + } + + if a.Kind() != b.Kind() { + return ErrTypeMismatch + } + + // Marshal and unmarshal time type will lose accuracy. Using unix nano to compare time type. + au := exportInterface(a).(time.Time).UnixNano() + bu := exportInterface(b).(time.Time).UnixNano() + + if au != bu { + d.cl.Add(UPDATE, path, exportInterface(a), exportInterface(b)) + } + + return nil +} diff --git a/vendor/github.com/r3labs/diff/v3/diff_uint.go b/vendor/github.com/r3labs/diff/v3/diff_uint.go new file mode 100644 index 0000000000..fbe133f1f9 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/diff_uint.go @@ -0,0 +1,35 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package diff + +import ( + "reflect" +) + +func (d *Differ) diffUint(path []string, a, b reflect.Value, parent interface{}) error { + if a.Kind() == reflect.Invalid { + d.cl.Add(CREATE, path, nil, exportInterface(b)) + return nil + } + + if b.Kind() == reflect.Invalid { + d.cl.Add(DELETE, path, exportInterface(a), nil) + return nil + } + + if a.Kind() != b.Kind() { + return ErrTypeMismatch + } + + if a.Uint() != b.Uint() { + if a.CanInterface() { + d.cl.Add(UPDATE, path, exportInterface(a), exportInterface(b), parent) + } else { + d.cl.Add(UPDATE, path, a.Uint(), b.Uint(), parent) + } + } + + return nil +} diff --git a/vendor/github.com/r3labs/diff/v3/error.go b/vendor/github.com/r3labs/diff/v3/error.go new file mode 100644 index 0000000000..0acc13ff09 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/error.go @@ -0,0 +1,74 @@ +package diff + +import ( + "fmt" +) + +var ( + // ErrTypeMismatch Compared types do not match + ErrTypeMismatch = NewError("types do not match") + // ErrInvalidChangeType The specified change values are not unsupported + ErrInvalidChangeType = NewError("change type must be one of 'create' or 'delete'") +) + +//our own version of an error, which can wrap others +type DiffError struct { + count int + message string + next error +} + +//Unwrap implement 1.13 unwrap feature for compatibility +func (s *DiffError) Unwrap() error { + return s.next +} + +//Error implements the error interface +func (s DiffError) Error() string { + cause := "" + if s.next != nil { + cause = s.next.Error() + } + return fmt.Sprintf(" %s (cause count %d)\n%s", s.message, s.count, cause) +} + +//AppendCause appends a new cause error to the chain +func (s *DiffError) WithCause(err error) *DiffError { + if s != nil && err != nil { + s.count++ + if s.next != nil { + if v, ok := err.(DiffError); ok { + s.next = v.WithCause(s.next) + } else if v, ok := err.(*DiffError); ok { + s.next = v.WithCause(s.next) + } else { + v = &DiffError{ + message: "auto wrapped error", + next: err, + } + s.next = v.WithCause(s.next) + } + } else { + s.next = err + } + } + return s +} + +//NewErrorf just give me a plain error with formatting +func NewErrorf(format string, messages ...interface{}) *DiffError { + return &DiffError{ + message: fmt.Sprintf(format, messages...), + } +} + +//NewError just give me a plain error +func NewError(message string, causes ...error) *DiffError { + s := &DiffError{ + message: message, + } + for _, cause := range causes { + s.WithCause(cause) // nolint: errcheck + } + return s +} diff --git a/vendor/github.com/r3labs/diff/v3/filter.go b/vendor/github.com/r3labs/diff/v3/filter.go new file mode 100644 index 0000000000..12e549a6ab --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/filter.go @@ -0,0 +1,22 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package diff + +import "regexp" + +func pathmatch(filter, path []string) bool { + for i, f := range filter { + if len(path) < i+1 { + return false + } + + matched, _ := regexp.MatchString(f, path[i]) + if !matched { + return false + } + } + + return true +} diff --git a/vendor/github.com/r3labs/diff/v3/options.go b/vendor/github.com/r3labs/diff/v3/options.go new file mode 100644 index 0000000000..fadbe86e67 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/options.go @@ -0,0 +1,93 @@ +package diff + +// ConvertTypes enables values that are convertible to the target type to be converted when patching +func ConvertCompatibleTypes() func(d *Differ) error { + return func(d *Differ) error { + d.ConvertCompatibleTypes = true + return nil + } +} + +// FlattenEmbeddedStructs determines whether fields of embedded structs should behave as if they are directly under the parent +func FlattenEmbeddedStructs() func(d *Differ) error { + return func(d *Differ) error { + d.FlattenEmbeddedStructs = true + return nil + } +} + +// SliceOrdering determines whether the ordering of items in a slice results in a change +func SliceOrdering(enabled bool) func(d *Differ) error { + return func(d *Differ) error { + d.SliceOrdering = enabled + return nil + } +} + +// TagName sets the tag name to use when getting field names and options +func TagName(tag string) func(d *Differ) error { + return func(d *Differ) error { + d.TagName = tag + return nil + } +} + +// DisableStructValues disables populating a separate change for each item in a struct, +// where the struct is being compared to a nil value +func DisableStructValues() func(d *Differ) error { + return func(d *Differ) error { + d.DisableStructValues = true + return nil + } +} + +// CustomValueDiffers allows you to register custom differs for specific types +func CustomValueDiffers(vd ...ValueDiffer) func(d *Differ) error { + return func(d *Differ) error { + d.customValueDiffers = append(d.customValueDiffers, vd...) + for k := range d.customValueDiffers { + d.customValueDiffers[k].InsertParentDiffer(d.diff) + } + return nil + } +} + +// AllowTypeMismatch changed behaviour to report value as "updated" when its type has changed instead of error +func AllowTypeMismatch(enabled bool) func(d *Differ) error { + return func(d *Differ) error { + d.AllowTypeMismatch = enabled + return nil + } +} + +//StructMapKeySupport - Changelog paths do not provided structured object values for maps that contain complex +//keys (such as other structs). You must enable this support via an option and it then uses msgpack to encode +//path elements that are structs. If you don't have this on, and try to patch, your apply will fail for that +//element. +func StructMapKeySupport() func(d *Differ) error { + return func(d *Differ) error { + d.StructMapKeys = true + return nil + } +} + +//DiscardComplexOrigin - by default, we are now keeping the complex struct associated with a create entry. +//This allows us to fix the merge to new object issue of not having enough change log details when allocating +//new objects. This however is a trade off of memory size and complexity vs correctness which is often only +//necessary when embedding structs in slices and arrays. It memory constrained environments, it may be desirable +//to turn this feature off however from a computational perspective, keeping the complex origin is actually quite +//cheap so, make sure you're extremely clear on the pitfalls of turning this off prior to doing so. +func DiscardComplexOrigin() func(d *Differ) error { + return func(d *Differ) error { + d.DiscardParent = true + return nil + } +} + +// Filter allows you to determine which fields the differ descends into +func Filter(f FilterFunc) func(d *Differ) error { + return func(d *Differ) error { + d.Filter = f + return nil + } +} diff --git a/vendor/github.com/r3labs/diff/v3/patch.go b/vendor/github.com/r3labs/diff/v3/patch.go new file mode 100644 index 0000000000..5814c536d7 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/patch.go @@ -0,0 +1,237 @@ +package diff + +import ( + "reflect" +) + +/** + This is a method of applying a changelog to a value or struct. change logs + should be generated with Diff and never manually created. This DOES NOT + apply fuzzy logic as would be in the case of a text patch. It does however + have a few additional features added to our struct tags. + + 1) create. This tag on a struct field indicates that the patch should + create the value if it's not there. I.e. if it's nil. This works for + pointers, maps and slices. + + 2) omitunequal. Generally, you don't want to do this, the expectation is + that if an item isn't there, you want to add it. For example, if your + diff shows an array element at index 6 is a string 'hello' but your target + only has 3 elements, none of them matching... you want to add 'hello' + regardless of the index. (think in a distributed context, another process + may have deleted more than one entry and 'hello' may no longer be in that + indexed spot. + + So given this scenario, the default behavior is to scan for the previous + value and replace it anyway, or simply append the new value. For maps the + default behavior is to simply add the key if it doesn't match. + + However, if you don't like the default behavior, and add the omitunequal + tag to your struct, patch will *NOT* update an array or map with the key + or array value unless they key or index contains a 'match' to the + previous value. In which case it will skip over that change. + + Patch is implemented as a best effort algorithm. That means you can receive + multiple nested errors and still successfully have a modified target. This + may even be acceptable depending on your use case. So keep in mind, just + because err != nil *DOESN'T* mean that the patch didn't accomplish your goal + in setting those changes that are actually available. For example, you may + diff two structs of the same type, then attempt to apply to an entirely + different struct that is similar in constitution (think interface here) and + you may in fact get all of the values populated you wished to anyway. +*/ + +//Not strictly necessary but might be nice in some cases +//go:generate stringer -type=PatchFlags +type PatchFlags uint32 + +const ( + OptionCreate PatchFlags = 1 << iota + OptionNoCreate + OptionOmitUnequal + OptionImmutable + FlagInvalidTarget + FlagApplied + FlagFailed + FlagCreated + FlagIgnored + FlagDeleted + FlagUpdated + FlagParentSetApplied + FlagParentSetFailed +) + +//PatchLogEntry defines how a DiffLog entry was applied +type PatchLogEntry struct { + Path []string `json:"path"` + From interface{} `json:"from"` + To interface{} `json:"to"` + Flags PatchFlags `json:"flags"` + Errors error `json:"errors"` +} +type PatchLog []PatchLogEntry + +//HasFlag - convenience function for users +func (p PatchLogEntry) HasFlag(flag PatchFlags) bool { + return (p.Flags & flag) != 0 +} + +//Applied - returns true if all change log entries were actually +// applied, regardless of if any errors were encountered +func (p PatchLog) Applied() bool { + if p.HasErrors() { + for _, ple := range p { + if !ple.HasFlag(FlagApplied) { + return false + } + } + } + return true +} + +//HasErrors - indicates if a patch log contains any errors +func (p PatchLog) HasErrors() (ret bool) { + for _, ple := range p { + if ple.Errors != nil { + ret = true + } + } + return +} + +//ErrorCount -- counts the number of errors encountered while patching +func (p PatchLog) ErrorCount() (ret uint) { + for _, ple := range p { + if ple.Errors != nil { + ret++ + } + } + return +} + +func Merge(original interface{}, changed interface{}, target interface{}) (PatchLog, error) { + d, _ := NewDiffer() + return d.Merge(original, changed, target) +} + +// Merge is a convenience function that diffs, the original and changed items +// and merges said changes with target all in one call. +func (d *Differ) Merge(original interface{}, changed interface{}, target interface{}) (PatchLog, error) { + StructMapKeySupport()(d) // nolint: errcheck + if cl, err := d.Diff(original, changed); err == nil { + return Patch(cl, target), nil + } else { + return nil, err + } +} + +func Patch(cl Changelog, target interface{}) (ret PatchLog) { + d, _ := NewDiffer() + return d.Patch(cl, target) +} + +//Patch... the missing feature. +func (d *Differ) Patch(cl Changelog, target interface{}) (ret PatchLog) { + for _, c := range cl { + ret = append(ret, NewPatchLogEntry(NewChangeValue(d, c, target))) + } + return ret +} + +//NewPatchLogEntry converts our complicated reflection based struct to +//a simpler format for the consumer +func NewPatchLogEntry(cv *ChangeValue) PatchLogEntry { + return PatchLogEntry{ + Path: cv.change.Path, + From: cv.change.From, + To: cv.change.To, + Flags: cv.flags, + Errors: cv.err, + } +} + +//NewChangeValue idiomatic constructor (also invokes render) +func NewChangeValue(d *Differ, c Change, target interface{}) (ret *ChangeValue) { + val := reflect.ValueOf(target) + ret = &ChangeValue{ + target: &val, + change: &c, + } + d.renderChangeTarget(ret) + return +} + +//renderChangeValue applies 'path' in change to target. nil check is foregone +// here as we control usage +func (d *Differ) renderChangeTarget(c *ChangeValue) { + //This particular change element may potentially have the immutable flag + if c.HasFlag(OptionImmutable) { + c.AddError(NewError("Option immutable set, cannot apply change")) + return + } //the we always set a failure, and only unset if we successfully render the element + c.SetFlag(FlagInvalidTarget) + + //substitute and solve for t (path) + switch c.target.Kind() { + + //path element that is a map + case reflect.Map: + //map elements are 'copies' and immutable so if we set the new value to the + //map prior to editing the value, it will fail to stick. To fix this, we + //defer the safe until the stack unwinds + m, k, v := d.renderMap(c) + defer d.updateMapEntry(c, m, k, v) + + //path element that is a slice + case reflect.Slice: + d.renderSlice(c) + + //walking a path means dealing with real elements + case reflect.Interface, reflect.Ptr: + if c.target.IsNil() { + n := reflect.New(c.target.Type().Elem()) + c.target.Set(n) + c.target = &n + d.renderChangeTarget(c) + return + } + + el := c.target.Elem() + c.target = &el + c.ClearFlag(FlagInvalidTarget) + + //path element that is a struct + case reflect.Struct: + d.patchStruct(c) + } + + //if for some reason, rendering this element fails, c will no longer be valid + //we are best effort though, so we keep on trucking + if !c.IsValid() { + c.AddError(NewErrorf("Unable to access path position %d. Target field is invalid", c.pos)) + } + + //we've taken care of this path element, are there any more? if so, process + //else, let's take some action + if c.pos < len(c.change.Path) && !c.HasFlag(FlagInvalidTarget) { + d.renderChangeTarget(c) + + } else { //we're at the end of the line... set the Value + switch c.change.Type { + case DELETE: + switch c.ParentKind() { + case reflect.Slice: + d.deleteSliceEntry(c) + case reflect.Struct: + d.deleteStructEntry(c) + default: + c.SetFlag(FlagIgnored) + } + case UPDATE, CREATE: + // this is generic because... we only deal in primitives here. AND + // the diff format To field already contains the correct type. + c.Set(reflect.ValueOf(c.change.To), d.ConvertCompatibleTypes) + c.SetFlag(FlagUpdated) + } + } +} diff --git a/vendor/github.com/r3labs/diff/v3/patch_map.go b/vendor/github.com/r3labs/diff/v3/patch_map.go new file mode 100644 index 0000000000..6c3f0352e8 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/patch_map.go @@ -0,0 +1,106 @@ +package diff + +import ( + "errors" + "reflect" + + "github.com/vmihailenco/msgpack/v5" +) + +// renderMap - handle map rendering for patch +func (d *Differ) renderMap(c *ChangeValue) (m, k, v *reflect.Value) { + //we must tease out the type of the key, we use the msgpack from diff to recreate the key + kt := c.target.Type().Key() + field := reflect.New(kt) + + if d.StructMapKeys { + if err := msgpack.Unmarshal([]byte(c.change.Path[c.pos]), field.Interface()); err != nil { + c.SetFlag(FlagIgnored) + c.AddError(NewError("Unable to unmarshal path element to target type for key in map", err)) + return + } + c.key = field.Elem() + } else { + c.key = reflect.ValueOf(c.change.Path[c.pos]) + } + + if c.target.IsNil() && c.target.IsValid() { + c.target.Set(reflect.MakeMap(c.target.Type())) + } + + // we need to check that MapIndex does not panic here + // when the key type is not a string + defer func() { + if err := recover(); err != nil { + switch x := err.(type) { + case error: + c.AddError(NewError("Unable to unmarshal path element to target type for key in map", x)) + case string: + c.AddError(NewError("Unable to unmarshal path element to target type for key in map", errors.New(x))) + } + c.SetFlag(FlagIgnored) + } + }() + + x := c.target.MapIndex(c.key) + + if !x.IsValid() && c.change.Type != DELETE && !c.HasFlag(OptionNoCreate) { + x = c.NewElement() + } + if x.IsValid() { //Map elements come out as read only so we must convert + nv := reflect.New(x.Type()).Elem() + nv.Set(x) + x = nv + } + + if x.IsValid() && !reflect.DeepEqual(c.change.From, x.Interface()) && + c.HasFlag(OptionOmitUnequal) { + c.SetFlag(FlagIgnored) + c.AddError(NewError("target change doesn't match original")) + return + } + mp := *c.target //these may change out from underneath us as we recurse + key := c.key //so we make copies and pass back pointers to them + c.swap(&x) + + return &mp, &key, &x + +} + +// updateMapEntry - deletes are special, they are handled differently based on options +// +// container type etc. We have to have special handling for each +// type. Set values are more generic even if they must be instanced +func (d *Differ) updateMapEntry(c *ChangeValue, m, k, v *reflect.Value) { + if k == nil || m == nil { + return + } + + switch c.change.Type { + case DELETE: + if c.HasFlag(FlagDeleted) { + return + } + + if !m.CanSet() && v.IsValid() && v.Kind() == reflect.Struct { + for x := 0; x < v.NumField(); x++ { + if !v.Field(x).IsZero() { + m.SetMapIndex(*k, *v) + return + } + } //if all the fields are zero, remove from map + } + + m.SetMapIndex(*k, reflect.Value{}) + c.SetFlag(FlagDeleted) + + case CREATE: + m.SetMapIndex(*k, *v) + c.SetFlag(FlagCreated) + + case UPDATE: + m.SetMapIndex(*k, *v) + c.SetFlag(FlagUpdated) + + } +} diff --git a/vendor/github.com/r3labs/diff/v3/patch_slice.go b/vendor/github.com/r3labs/diff/v3/patch_slice.go new file mode 100644 index 0000000000..9a703e57a8 --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/patch_slice.go @@ -0,0 +1,78 @@ +package diff + +/** + Types are being split out to more closely follow the library structure already + in place. Keeps the file simpler as well. +*/ +import ( + "reflect" + "strconv" +) + +//renderSlice - handle slice rendering for patch +func (d *Differ) renderSlice(c *ChangeValue) { + + var err error + field := c.change.Path[c.pos] + + //field better be an index of the slice + if c.index, err = strconv.Atoi(field); err != nil { + //if struct element is has identifier, use it instead + if identifier(d.TagName, reflect.Zero(c.target.Type().Elem())) != nil { + for c.index = 0; c.index < c.Len(); c.index++ { + if identifier(d.TagName, c.Index(c.index)) == field { + break + } + } + } else { + c.AddError(NewErrorf("invalid index in path. %s is not a number", field). + WithCause(err)) + } + } + var x reflect.Value + if c.Len() > c.index { + x = c.Index(c.index) + } else if c.change.Type == CREATE && !c.HasFlag(OptionNoCreate) { + x = c.NewArrayElement() + } + if !x.IsValid() { + if !c.HasFlag(OptionOmitUnequal) { + c.AddError(NewErrorf("Value index %d is invalid", c.index). + WithCause(NewError("scanning for Value index"))) + for c.index = 0; c.index < c.Len(); c.index++ { + y := c.Index(c.index) + if reflect.DeepEqual(y, c.change.From) { + c.AddError(NewErrorf("Value changed index to %d", c.index)) + x = y + break + } + } + } + } + if !x.IsValid() && c.change.Type != DELETE && !c.HasFlag(OptionNoCreate) { + x = c.NewArrayElement() + } + if !x.IsValid() && c.change.Type == DELETE { + c.index = -1 //no existing element to delete so don't bother + } + c.swap(&x) //containers must swap out the parent Value +} + +//deleteSliceEntry - deletes are special, they are handled differently based on options +// container type etc. We have to have special handling for each +// type. Set values are more generic even if they must be instanced +func (d *Differ) deleteSliceEntry(c *ChangeValue) { + //for a slice with only one element + if c.ParentLen() == 1 && c.index != -1 { + c.ParentSet(reflect.MakeSlice(c.parent.Type(), 0, 0), d.ConvertCompatibleTypes) + c.SetFlag(FlagDeleted) + //for a slice with multiple elements + } else if c.index != -1 { //this is an array delete the element from the parent + c.ParentIndex(c.index).Set(c.ParentIndex(c.ParentLen() - 1)) + c.ParentSet(c.parent.Slice(0, c.ParentLen()-1), d.ConvertCompatibleTypes) + c.SetFlag(FlagDeleted) + //for other slice elements, we ignore + } else { + c.SetFlag(FlagIgnored) + } +} diff --git a/vendor/github.com/r3labs/diff/v3/patch_struct.go b/vendor/github.com/r3labs/diff/v3/patch_struct.go new file mode 100644 index 0000000000..4e2d247f1f --- /dev/null +++ b/vendor/github.com/r3labs/diff/v3/patch_struct.go @@ -0,0 +1,66 @@ +package diff + +import "reflect" + +/** + Types are being split out to more closely follow the library structure already + in place. Keeps the file simpler as well. +*/ + +type structField struct { + f reflect.StructField + v reflect.Value +} + +func getNestedFields(v reflect.Value, flattenEmbedded bool) []structField { + fields := make([]structField, 0) + + for i := 0; i < v.NumField(); i++ { + f := v.Type().Field(i) + fv := v.Field(i) + + if fv.Kind() == reflect.Struct && f.Anonymous && flattenEmbedded { + fields = append(fields, getNestedFields(fv, flattenEmbedded)...) + } else { + fields = append(fields, structField{f, fv}) + } + } + + return fields +} + +//patchStruct - handles the rendering of a struct field +func (d *Differ) patchStruct(c *ChangeValue) { + + field := c.change.Path[c.pos] + + structFields := getNestedFields(*c.target, d.FlattenEmbeddedStructs) + for _, structField := range structFields { + f := structField.f + tname := tagName(d.TagName, f) + if tname == "-" { + continue + } + if tname == field || f.Name == field { + x := structField.v + if hasTagOption(d.TagName, f, "nocreate") { + c.SetFlag(OptionNoCreate) + } + if hasTagOption(d.TagName, f, "omitunequal") { + c.SetFlag(OptionOmitUnequal) + } + if hasTagOption(d.TagName, f, "immutable") { + c.SetFlag(OptionImmutable) + } + c.swap(&x) + break + } + } +} + +//track and zero out struct members +func (d *Differ) deleteStructEntry(c *ChangeValue) { + + //deleting a struct value set's it to the 'basic' type + c.Set(reflect.Zero(c.target.Type()), d.ConvertCompatibleTypes) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 5836d02829..d1864beeb2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -555,6 +555,9 @@ github.com/prometheus/common/model github.com/prometheus/procfs github.com/prometheus/procfs/internal/fs github.com/prometheus/procfs/internal/util +# github.com/r3labs/diff/v3 v3.0.1 +## explicit; go 1.13 +github.com/r3labs/diff/v3 # github.com/radovskyb/watcher v1.0.7 ## explicit github.com/radovskyb/watcher From 8a1b8a36745975509656d2ee0d701f8531cd9101 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jan 2024 11:40:25 +1300 Subject: [PATCH 149/413] get merged changes --- .../utils/utils.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index b390296014..d875be8736 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -75,7 +75,7 @@ func pumpSettingsHasBolus(bsonData bson.M) bool { return false } -func logUpdates(id string, updates interface{}) { +func logUpdates(updates interface{}) { f, err := os.OpenFile("update.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { @@ -83,7 +83,7 @@ func logUpdates(id string, updates interface{}) { os.Exit(1) } defer f.Close() - f.WriteString(fmt.Sprintf("%s %v \n", id, updates)) + f.WriteString(fmt.Sprintf("%#v\n", updates)) // buf := &bytes.Buffer{} // if err := json.Indent(buf, updatesJSON, "", "\t"); err == nil { // f.WriteString(fmt.Sprintf("%s \n", buf.String())) @@ -175,8 +175,18 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { } //get dif - changelog, _ := diff.Diff(ojbData, processedData) - logUpdates(fmt.Sprintf("%s", ojbData["_id"]), changelog) + toApply := map[string]interface{}{} + //changelog, _ := diff.Diff(ojbData, processedData, diff.StructMapKeySupport()) + + patchlog, _ := diff.Merge(ojbData, processedData, toApply) + + if patchlog.HasErrors() { + log.Printf("merge errors %d", patchlog.ErrorCount()) + } + + toApply["_id"] = ojbData["_id"] + + logUpdates(toApply) // log.Printf("changes %v", changelog) From 0a0098fca3477e4ee7753070ed08e0937fc92b20 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jan 2024 11:46:06 +1300 Subject: [PATCH 150/413] fix --- migrations/20231128_jellyfish_migration/utils/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index d875be8736..1f745032cc 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -178,7 +178,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { toApply := map[string]interface{}{} //changelog, _ := diff.Diff(ojbData, processedData, diff.StructMapKeySupport()) - patchlog, _ := diff.Merge(ojbData, processedData, toApply) + patchlog, _ := diff.Merge(ojbData, processedData, &toApply) if patchlog.HasErrors() { log.Printf("merge errors %d", patchlog.ErrorCount()) From e7d8f9e8a1bc0e19c8b804af9246bdfaf5ed170d Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jan 2024 12:02:22 +1300 Subject: [PATCH 151/413] try patch --- .../20231128_jellyfish_migration/utils/utils.go | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 1f745032cc..e0e62a70f5 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -176,23 +176,15 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { //get dif toApply := map[string]interface{}{} - //changelog, _ := diff.Diff(ojbData, processedData, diff.StructMapKeySupport()) - - patchlog, _ := diff.Merge(ojbData, processedData, &toApply) + changelog, _ := diff.Diff(ojbData, processedData, diff.StructMapKeySupport()) + patchlog := diff.Patch(changelog, &toApply) if patchlog.HasErrors() { - log.Printf("merge errors %d", patchlog.ErrorCount()) + log.Printf("patch errors %d", patchlog.ErrorCount()) } - toApply["_id"] = ojbData["_id"] logUpdates(toApply) - - // log.Printf("changes %v", changelog) - - // if string(incomingJSONData) != string(outgoingJSONData) { - // logUpdates(outgoingJSONData) - // } return *datum, nil } From 5db565e644295e9ff5e1b8421d59cd5fb05bb525 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jan 2024 12:08:34 +1300 Subject: [PATCH 152/413] just use change log --- .../utils/utils.go | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index e0e62a70f5..ac8a371f27 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -1,6 +1,7 @@ package utils import ( + "bytes" "encoding/json" "fmt" "log" @@ -83,11 +84,12 @@ func logUpdates(updates interface{}) { os.Exit(1) } defer f.Close() - f.WriteString(fmt.Sprintf("%#v\n", updates)) - // buf := &bytes.Buffer{} - // if err := json.Indent(buf, updatesJSON, "", "\t"); err == nil { - // f.WriteString(fmt.Sprintf("%s \n", buf.String())) - // } + //f.WriteString(fmt.Sprintf("%#v\n", updates)) + updatesJSON, _ := json.Marshal(updates) + buf := &bytes.Buffer{} + if err := json.Indent(buf, updatesJSON, "", "\t"); err == nil { + f.WriteString(fmt.Sprintf("%s \n", buf.String())) + } } func ProcessDatum(bsonData bson.M) (data.Datum, error) { @@ -175,16 +177,13 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { } //get dif - toApply := map[string]interface{}{} + //toApply := map[string]interface{}{} changelog, _ := diff.Diff(ojbData, processedData, diff.StructMapKeySupport()) - patchlog := diff.Patch(changelog, &toApply) + //patchlog := diff.Patch(changelog, &toApply) - if patchlog.HasErrors() { - log.Printf("patch errors %d", patchlog.ErrorCount()) - } - toApply["_id"] = ojbData["_id"] + //toApply["_id"] = ojbData["_id"] - logUpdates(toApply) + logUpdates(changelog) return *datum, nil } From ee2e470c7ad45de3186c6d2a69543e5df35f2f9c Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jan 2024 12:24:14 +1300 Subject: [PATCH 153/413] include id --- .../20231128_jellyfish_migration/utils/utils.go | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index ac8a371f27..9694874df0 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -1,7 +1,6 @@ package utils import ( - "bytes" "encoding/json" "fmt" "log" @@ -76,7 +75,7 @@ func pumpSettingsHasBolus(bsonData bson.M) bool { return false } -func logUpdates(updates interface{}) { +func logUpdates(id string, updates interface{}) { f, err := os.OpenFile("update.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { @@ -84,12 +83,7 @@ func logUpdates(updates interface{}) { os.Exit(1) } defer f.Close() - //f.WriteString(fmt.Sprintf("%#v\n", updates)) - updatesJSON, _ := json.Marshal(updates) - buf := &bytes.Buffer{} - if err := json.Indent(buf, updatesJSON, "", "\t"); err == nil { - f.WriteString(fmt.Sprintf("%s \n", buf.String())) - } + f.WriteString(fmt.Sprintf("{id:%s, changes:%#v}\n", id, updates)) } func ProcessDatum(bsonData bson.M) (data.Datum, error) { @@ -183,7 +177,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { //toApply["_id"] = ojbData["_id"] - logUpdates(changelog) + logUpdates(fmt.Sprintf("%s", ojbData["_id"]), changelog) return *datum, nil } From 8c26b2728031f244dd3046531913072da5e2e487 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jan 2024 12:38:33 +1300 Subject: [PATCH 154/413] updates --- .../20231128_jellyfish_migration/utils/utils.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 9694874df0..92b140792d 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -83,7 +83,13 @@ func logUpdates(id string, updates interface{}) { os.Exit(1) } defer f.Close() - f.WriteString(fmt.Sprintf("{id:%s, changes:%#v}\n", id, updates)) + + updatesJSON, _ := json.Marshal(updates) + f.WriteString(fmt.Sprintf("{id:%s, updates:%s}\n", id, string(updatesJSON))) + // buf := &bytes.Buffer{} + // if err := json.Indent(buf, updatesJSON, "", "\t"); err == nil { + // f.WriteString(fmt.Sprintf("%s \n", buf.String())) + // } } func ProcessDatum(bsonData bson.M) (data.Datum, error) { @@ -170,13 +176,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { return nil, err } - //get dif - //toApply := map[string]interface{}{} changelog, _ := diff.Diff(ojbData, processedData, diff.StructMapKeySupport()) - //patchlog := diff.Patch(changelog, &toApply) - - //toApply["_id"] = ojbData["_id"] - logUpdates(fmt.Sprintf("%s", ojbData["_id"]), changelog) return *datum, nil } From 00d1c2905f53461654e88fea11ce92e42a965fcc Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jan 2024 13:54:16 +1300 Subject: [PATCH 155/413] use bson and then remove ignored fields --- .../utils/utils.go | 44 +++++++++++++++---- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 92b140792d..cea5b973a8 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -83,13 +83,20 @@ func logUpdates(id string, updates interface{}) { os.Exit(1) } defer f.Close() + updatesJSON, _ := json.Marshal(updates) + f.WriteString(fmt.Sprintf(`{"id":"%s", "updates":%s}\n`, id, string(updatesJSON))) +} +func logUpdates2(id string, updates interface{}) { + f, err := os.OpenFile("update2.log", + os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Println(err) + os.Exit(1) + } + defer f.Close() updatesJSON, _ := json.Marshal(updates) - f.WriteString(fmt.Sprintf("{id:%s, updates:%s}\n", id, string(updatesJSON))) - // buf := &bytes.Buffer{} - // if err := json.Indent(buf, updatesJSON, "", "\t"); err == nil { - // f.WriteString(fmt.Sprintf("%s \n", buf.String())) - // } + f.WriteString(fmt.Sprintf(`{"id":"%s", "updates":%s}\n`, id, string(updatesJSON))) } func ProcessDatum(bsonData bson.M) (data.Datum, error) { @@ -129,16 +136,33 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { } } - //marshal to json pretty print as source of comparison - incomingJSONData, err := json.Marshal(bsonData) + incomingJSONData, err := bson.Marshal(bsonData) if err != nil { return nil, err } ojbData := map[string]interface{}{} - if err := json.Unmarshal(incomingJSONData, &ojbData); err != nil { + err = bson.Unmarshal(incomingJSONData, &ojbData) + if err != nil { return nil, err } + //marshal to json pretty print as source of comparison + // incomingJSONData, err := json.Marshal(bsonData) + // if err != nil { + // return nil, err + // } + // ojbData := map[string]interface{}{} + // if err := json.Unmarshal(incomingJSONData, &ojbData); err != nil { + // return nil, err + // } + + //remove fields + ignoreFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "uploadId"} + + for _, field := range ignoreFields { + delete(ojbData, field) + } + parser := structureParser.NewObject(&ojbData) validator := structureValidator.New() normalizer := dataNormalizer.New() @@ -178,6 +202,10 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { changelog, _ := diff.Diff(ojbData, processedData, diff.StructMapKeySupport()) logUpdates(fmt.Sprintf("%s", ojbData["_id"]), changelog) + + changelog2, _ := diff.Diff(processedData, ojbData, diff.StructMapKeySupport()) + logUpdates2(fmt.Sprintf("%s", ojbData["_id"]), changelog2) + return *datum, nil } From 1482580c2345ce117d31142ce23897492f1eee02 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jan 2024 14:35:53 +1300 Subject: [PATCH 156/413] logging raw data --- .../20231128_jellyfish_migration/utils/utils.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index cea5b973a8..6ade9dc543 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -146,6 +146,10 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { return nil, err } + log.Println("INCOMING") + log.Println(string(incomingJSONData)) + log.Printf("%v", ojbData) + //marshal to json pretty print as source of comparison // incomingJSONData, err := json.Marshal(bsonData) // if err != nil { @@ -157,11 +161,11 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { // } //remove fields - ignoreFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "uploadId"} + // ignoreFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "uploadId"} - for _, field := range ignoreFields { - delete(ojbData, field) - } + // for _, field := range ignoreFields { + // delete(ojbData, field) + // } parser := structureParser.NewObject(&ojbData) validator := structureValidator.New() @@ -195,6 +199,9 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { return nil, err } + log.Println("PARSED") + log.Println(string(outgoingJSONData)) + processedData := map[string]interface{}{} if err := json.Unmarshal(outgoingJSONData, &processedData); err != nil { return nil, err From d8d9946fc38a617fc992e2b13e176927a92857b4 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jan 2024 14:45:41 +1300 Subject: [PATCH 157/413] json not bson --- .../utils/utils.go | 25 ++++--------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 6ade9dc543..dd97cf9cfd 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -136,29 +136,15 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { } } - incomingJSONData, err := bson.Marshal(bsonData) + incomingJSONData, err := json.Marshal(bsonData) if err != nil { return nil, err } ojbData := map[string]interface{}{} - err = bson.Unmarshal(incomingJSONData, &ojbData) - if err != nil { + if err := json.Unmarshal(incomingJSONData, &ojbData); err != nil { return nil, err } - - log.Println("INCOMING") - log.Println(string(incomingJSONData)) - log.Printf("%v", ojbData) - - //marshal to json pretty print as source of comparison - // incomingJSONData, err := json.Marshal(bsonData) - // if err != nil { - // return nil, err - // } - // ojbData := map[string]interface{}{} - // if err := json.Unmarshal(incomingJSONData, &ojbData); err != nil { - // return nil, err - // } + log.Printf("INCOMING: %v\n", ojbData) //remove fields // ignoreFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "uploadId"} @@ -199,14 +185,13 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { return nil, err } - log.Println("PARSED") - log.Println(string(outgoingJSONData)) - processedData := map[string]interface{}{} if err := json.Unmarshal(outgoingJSONData, &processedData); err != nil { return nil, err } + log.Printf("PARSED: %v\n", processedData) + changelog, _ := diff.Diff(ojbData, processedData, diff.StructMapKeySupport()) logUpdates(fmt.Sprintf("%s", ojbData["_id"]), changelog) From 5b943fbb696d079e1c5f58bdf9e0ab26f8809dc2 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jan 2024 15:02:50 +1300 Subject: [PATCH 158/413] logging raw result --- migrations/20231128_jellyfish_migration/utils/utils.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index dd97cf9cfd..6086df2374 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -144,7 +144,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { if err := json.Unmarshal(incomingJSONData, &ojbData); err != nil { return nil, err } - log.Printf("INCOMING: %v\n", ojbData) + //log.Printf("INCOMING: %v\n", ojbData) //remove fields // ignoreFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "uploadId"} @@ -190,13 +190,10 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { return nil, err } - log.Printf("PARSED: %v\n", processedData) - changelog, _ := diff.Diff(ojbData, processedData, diff.StructMapKeySupport()) logUpdates(fmt.Sprintf("%s", ojbData["_id"]), changelog) - changelog2, _ := diff.Diff(processedData, ojbData, diff.StructMapKeySupport()) - logUpdates2(fmt.Sprintf("%s", ojbData["_id"]), changelog2) + logUpdates2(fmt.Sprintf("%s", ojbData["_id"]), string(outgoingJSONData)) return *datum, nil } From 9e159c4fc3bd19bcd9f9bd810e536e49dc82f333 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jan 2024 15:48:24 +1300 Subject: [PATCH 159/413] show parser errs --- .../20231128_jellyfish_migration/utils/utils.go | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 6086df2374..3fce1bfe82 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -84,10 +84,10 @@ func logUpdates(id string, updates interface{}) { } defer f.Close() updatesJSON, _ := json.Marshal(updates) - f.WriteString(fmt.Sprintf(`{"id":"%s", "updates":%s}\n`, id, string(updatesJSON))) + f.WriteString(fmt.Sprintf(`{"id":"%s", "updates":%s}`, id, string(updatesJSON))) } -func logUpdates2(id string, updates interface{}) { +func logUpdates2(id string, updates []byte) { f, err := os.OpenFile("update2.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { @@ -95,8 +95,7 @@ func logUpdates2(id string, updates interface{}) { os.Exit(1) } defer f.Close() - updatesJSON, _ := json.Marshal(updates) - f.WriteString(fmt.Sprintf(`{"id":"%s", "updates":%s}\n`, id, string(updatesJSON))) + f.WriteString(fmt.Sprintf(`{"id":"%s", "updates":%s}`, id, string(updates))) } func ProcessDatum(bsonData bson.M) (data.Datum, error) { @@ -144,7 +143,6 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { if err := json.Unmarshal(incomingJSONData, &ojbData); err != nil { return nil, err } - //log.Printf("INCOMING: %v\n", ojbData) //remove fields // ignoreFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "uploadId"} @@ -167,10 +165,9 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { parser.NotParsed() - // TODO lots of `ErrorNotParsed` exceptions - // if err := parser.Error(); err != nil { - // parseErr = errors.Join(parseErr, err) - // } + if err := parser.Error(); err != nil { + return nil, err + } if err := validator.Error(); err != nil { return nil, err @@ -193,7 +190,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { changelog, _ := diff.Diff(ojbData, processedData, diff.StructMapKeySupport()) logUpdates(fmt.Sprintf("%s", ojbData["_id"]), changelog) - logUpdates2(fmt.Sprintf("%s", ojbData["_id"]), string(outgoingJSONData)) + logUpdates2(fmt.Sprintf("%s", ojbData["_id"]), outgoingJSONData) return *datum, nil } From f4584b9ddf15098fdd6c42b65bb9066a2f79c455 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jan 2024 16:04:56 +1300 Subject: [PATCH 160/413] get datum fields --- .../utils/utils.go | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 3fce1bfe82..5a8b140a19 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -10,6 +10,7 @@ import ( "github.com/r3labs/diff/v3" "go.mongodb.org/mongo-driver/bson" + "golang.org/x/exp/maps" "github.com/tidepool-org/platform/data" @@ -101,6 +102,7 @@ func logUpdates2(id string, updates []byte) { func ProcessDatum(bsonData bson.M) (data.Datum, error) { dType := fmt.Sprintf("%v", bsonData["type"]) + dID := fmt.Sprintf("%v", bsonData["_id"]) if dType == pump.Type { if boluses := bsonData["bolus"]; boluses != nil { bsonData["boluses"] = boluses @@ -144,12 +146,14 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { return nil, err } + log.Printf("INCOMING: id[%s] type[%s] feilds[%s]", dID, dType, maps.Keys(ojbData)) + //remove fields - // ignoreFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "uploadId"} + unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "uploadId"} - // for _, field := range ignoreFields { - // delete(ojbData, field) - // } + for _, unparsed := range unparsedFields { + delete(ojbData, unparsed) + } parser := structureParser.NewObject(&ojbData) validator := structureValidator.New() @@ -160,7 +164,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { (*datum).Validate(validator) (*datum).Normalize(normalizer) } else { - return nil, errorsP.Newf("no datum returned for id=[%s]", ojbData["_id"]) + return nil, errorsP.Newf("no datum returned for id=[%s]", dID) } parser.NotParsed() @@ -188,9 +192,9 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { } changelog, _ := diff.Diff(ojbData, processedData, diff.StructMapKeySupport()) - logUpdates(fmt.Sprintf("%s", ojbData["_id"]), changelog) + logUpdates(dID, changelog) - logUpdates2(fmt.Sprintf("%s", ojbData["_id"]), outgoingJSONData) + logUpdates2(dID, outgoingJSONData) return *datum, nil } From cf2bd15129d59a73e1ed7973e365531893b1da0b Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jan 2024 16:09:21 +1300 Subject: [PATCH 161/413] remove other un parsed fields --- migrations/20231128_jellyfish_migration/utils/utils.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 5a8b140a19..d55fcd8d7a 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -149,12 +149,15 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { log.Printf("INCOMING: id[%s] type[%s] feilds[%s]", dID, dType, maps.Keys(ojbData)) //remove fields - unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "uploadId"} + // _deduplicator _id _userId _active id payload time _version _schemaVersion deviceId guid units uploadId value _groupId type createdTime + unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "uploadId", "guid", "id", "createdTime"} for _, unparsed := range unparsedFields { delete(ojbData, unparsed) } + log.Printf("UPDATED: id[%s] type[%s] feilds[%s]", dID, dType, maps.Keys(ojbData)) + parser := structureParser.NewObject(&ojbData) validator := structureValidator.New() normalizer := dataNormalizer.New() From d42312d607415075d315a61e8fbddb38f6a2aa95 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jan 2024 16:11:33 +1300 Subject: [PATCH 162/413] remove schema version --- migrations/20231128_jellyfish_migration/utils/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index d55fcd8d7a..d5f1bbd453 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -150,7 +150,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { //remove fields // _deduplicator _id _userId _active id payload time _version _schemaVersion deviceId guid units uploadId value _groupId type createdTime - unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "uploadId", "guid", "id", "createdTime"} + unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "uploadId", "guid", "id", "createdTime", "_schemaVersion"} for _, unparsed := range unparsedFields { delete(ojbData, unparsed) From 154ac2b75b74f063df8a21dfeb8ccd0fa965acc2 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jan 2024 16:42:53 +1300 Subject: [PATCH 163/413] context for parsing errors --- .../utils/utils.go | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index d5f1bbd453..8354ffcb2b 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -88,7 +88,7 @@ func logUpdates(id string, updates interface{}) { f.WriteString(fmt.Sprintf(`{"id":"%s", "updates":%s}`, id, string(updatesJSON))) } -func logUpdates2(id string, updates []byte) { +func logUpdates2(id string, original []byte, updated []byte) { f, err := os.OpenFile("update2.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { @@ -96,7 +96,7 @@ func logUpdates2(id string, updates []byte) { os.Exit(1) } defer f.Close() - f.WriteString(fmt.Sprintf(`{"id":"%s", "updates":%s}`, id, string(updates))) + f.WriteString(fmt.Sprintf(`{"_id":"%s", "jellyfish":%s "platform":%s},`, id, string(original), string(updated))) } func ProcessDatum(bsonData bson.M) (data.Datum, error) { @@ -146,18 +146,20 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { return nil, err } - log.Printf("INCOMING: id[%s] type[%s] feilds[%s]", dID, dType, maps.Keys(ojbData)) - - //remove fields - // _deduplicator _id _userId _active id payload time _version _schemaVersion deviceId guid units uploadId value _groupId type createdTime - unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "uploadId", "guid", "id", "createdTime", "_schemaVersion"} - + //cleanup + incomingKeys := maps.Keys(ojbData) + unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "_schemaVersion", "uploadId", "guid", "id", "createdTime"} for _, unparsed := range unparsedFields { delete(ojbData, unparsed) } + cleanedKeys := maps.Keys(ojbData) - log.Printf("UPDATED: id[%s] type[%s] feilds[%s]", dID, dType, maps.Keys(ojbData)) + cleanedJSONData, err := json.Marshal(ojbData) + if err != nil { + return nil, err + } + //parsing parser := structureParser.NewObject(&ojbData) validator := structureValidator.New() normalizer := dataNormalizer.New() @@ -173,7 +175,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { parser.NotParsed() if err := parser.Error(); err != nil { - return nil, err + return nil, errorsP.Wrap(err, fmt.Sprintf("_id[%s] type[%s] original[%s] cleaned[%s]", dID, dType, incomingKeys, cleanedKeys)) } if err := validator.Error(); err != nil { @@ -197,7 +199,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { changelog, _ := diff.Diff(ojbData, processedData, diff.StructMapKeySupport()) logUpdates(dID, changelog) - logUpdates2(dID, outgoingJSONData) + logUpdates2(dID, cleanedJSONData, outgoingJSONData) return *datum, nil } From b6eddf99d4b71e56456ce45916e0a031ed3b7f58 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jan 2024 17:25:36 +1300 Subject: [PATCH 164/413] cleaner diff --- .../utils/utils.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 8354ffcb2b..e169dfc0b8 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -76,8 +76,8 @@ func pumpSettingsHasBolus(bsonData bson.M) bool { return false } -func logUpdates(id string, updates interface{}) { - f, err := os.OpenFile("update.log", +func logDiff(id string, updates interface{}) { + f, err := os.OpenFile("diff.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { log.Println(err) @@ -85,18 +85,18 @@ func logUpdates(id string, updates interface{}) { } defer f.Close() updatesJSON, _ := json.Marshal(updates) - f.WriteString(fmt.Sprintf(`{"id":"%s", "updates":%s}`, id, string(updatesJSON))) + f.WriteString(fmt.Sprintf(`{"_id":"%s","diff":%s},`, id, string(updatesJSON))) } -func logUpdates2(id string, original []byte, updated []byte) { - f, err := os.OpenFile("update2.log", +func logBeforeAndAfter(id string, original []byte, updated []byte) { + f, err := os.OpenFile("changes.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { log.Println(err) os.Exit(1) } defer f.Close() - f.WriteString(fmt.Sprintf(`{"_id":"%s", "jellyfish":%s "platform":%s},`, id, string(original), string(updated))) + f.WriteString(fmt.Sprintf(`{"_id":"%s","jellyfish":%s,"platform":%s},`, id, string(original), string(updated))) } func ProcessDatum(bsonData bson.M) (data.Datum, error) { @@ -148,7 +148,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { //cleanup incomingKeys := maps.Keys(ojbData) - unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "_schemaVersion", "uploadId", "guid", "id", "createdTime"} + unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "_schemaVersion", "uploadId", "guid", "createdTime"} for _, unparsed := range unparsedFields { delete(ojbData, unparsed) } @@ -197,9 +197,9 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { } changelog, _ := diff.Diff(ojbData, processedData, diff.StructMapKeySupport()) - logUpdates(dID, changelog) + logDiff(dID, changelog) - logUpdates2(dID, cleanedJSONData, outgoingJSONData) + logBeforeAndAfter(dID, cleanedJSONData, outgoingJSONData) return *datum, nil } From cfe2927f8ca6ae4d7e6a44d9a67ecdf286922ad9 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 1 Feb 2024 10:32:52 +1300 Subject: [PATCH 165/413] formatting --- data/blood/glucose/glucose.go | 14 +++++++++++++ data/blood/glucose/glucose_test.go | 1 + .../jellyfish_migration.go | 2 +- .../utils/migrationUtil.go | 2 +- .../utils/utils.go | 21 +++++++++++++++---- 5 files changed, 34 insertions(+), 6 deletions(-) diff --git a/data/blood/glucose/glucose.go b/data/blood/glucose/glucose.go index 32ca889dd9..791bdae799 100644 --- a/data/blood/glucose/glucose.go +++ b/data/blood/glucose/glucose.go @@ -63,6 +63,20 @@ func NormalizeValueForUnits(value *float64, units *string) *float64 { intValue := int(*value/MmolLToMgdLConversionFactor*MmolLToMgdLPrecisionFactor + 0.5) floatValue := float64(intValue) / MmolLToMgdLPrecisionFactor return &floatValue + + case MmolL, Mmoll: + + mgdlVal := *value * MmolLToMgdLConversionFactor + + intValue := int(mgdlVal/MmolLToMgdLConversionFactor*MmolLToMgdLPrecisionFactor + 0.5) + floatValue := float64(intValue) / MmolLToMgdLPrecisionFactor + return &floatValue + + //if len([]rune(strVal)) > 8 { + // floatValue := math.Floor(*value*MmolLToMgdLPrecisionFactor) / MmolLToMgdLPrecisionFactor + // return &floatValue + //} + //return value } } return value diff --git a/data/blood/glucose/glucose_test.go b/data/blood/glucose/glucose_test.go index cf726fd967..39940c5f95 100644 --- a/data/blood/glucose/glucose_test.go +++ b/data/blood/glucose/glucose_test.go @@ -107,6 +107,7 @@ var _ = Describe("Glucose", func() { Entry("returns unchanged value for mmol/l units", pointer.FromFloat64(10.0), pointer.FromString("mmol/l"), pointer.FromFloat64(10.0)), Entry("returns converted value for mg/dL units", pointer.FromFloat64(180.0), pointer.FromString("mg/dL"), pointer.FromFloat64(9.99135)), Entry("returns converted value for mg/dl units", pointer.FromFloat64(180.0), pointer.FromString("mg/dl"), pointer.FromFloat64(9.99135)), + Entry("returns converted value for mmol/L units with incorrect precision", pointer.FromFloat64(4.88465823212007), pointer.FromString("mmol/L"), pointer.FromFloat64(4.88466)), ) It("properly normalizes a range of mmol/L values", func() { diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index b881ecb861..2a49d495fe 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -319,7 +319,7 @@ func (m *Migration) fetchAndProcess() bool { } _, err := utils.ProcessDatum(item) if err != nil { - m.migrationUtil.OnError(err, fmt.Sprintf("%v", item["_id"]), fmt.Sprintf("type [%v]", item["type"])) + m.migrationUtil.OnError(err, fmt.Sprintf("%v", item["_id"]), "processing") } all = append(all, item) } diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 8a1a608b10..62944bae42 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -218,7 +218,7 @@ func (c *MigrationUtilConfig) SetStopOnErr(stopOnErr bool) *MigrationUtilConfig // - write error to file `error.log` in directory cli is running in // - optionally stop the operation if stopOnErr is true in the config func (m *migrationUtil) OnError(reportErr error, id string, msg string) { - var errFormat = "[id=%s] %s %s\n" + var errFormat = "[_id=%s] %s %s\n" if reportErr != nil { m.errorsCount++ f, err := os.OpenFile("error.log", diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index e169dfc0b8..e40dc339b2 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -17,6 +17,7 @@ import ( "github.com/tidepool-org/platform/data/deduplicator/deduplicator" "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/data/types/basal" + "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" "github.com/tidepool-org/platform/data/types/blood/ketone" @@ -103,12 +104,24 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { dType := fmt.Sprintf("%v", bsonData["type"]) dID := fmt.Sprintf("%v", bsonData["_id"]) - if dType == pump.Type { + + switch dType { + case pump.Type: if boluses := bsonData["bolus"]; boluses != nil { bsonData["boluses"] = boluses delete(bsonData, "bolus") } + // case selfmonitored.Type, ketone.Type, continuous.Type: + // units := fmt.Sprintf("%v", bsonData["units"]) + // if units == glucose.MmolL || units == glucose.Mmoll { + + // if val, ok := bsonData["value"].(float64); ok { + + // } + + // } } + if payload := bsonData["payload"]; payload != nil { if _, ok := payload.(string); ok { dataBytes, err := bson.Marshal(payload) @@ -147,8 +160,8 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { } //cleanup - incomingKeys := maps.Keys(ojbData) - unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "_schemaVersion", "uploadId", "guid", "createdTime"} + //incomingKeys := maps.Keys(ojbData) + unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "_schemaVersion"} for _, unparsed := range unparsedFields { delete(ojbData, unparsed) } @@ -175,7 +188,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { parser.NotParsed() if err := parser.Error(); err != nil { - return nil, errorsP.Wrap(err, fmt.Sprintf("_id[%s] type[%s] original[%s] cleaned[%s]", dID, dType, incomingKeys, cleanedKeys)) + return nil, errorsP.Wrap(err, fmt.Sprintf("type[%s] cleaned[%s]", dType, cleanedKeys)) } if err := validator.Error(); err != nil { From 10bfce2b2c1005b3cda94d70b08de7291beb6871 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 1 Feb 2024 11:28:09 +1300 Subject: [PATCH 166/413] try origin --- .../20231128_jellyfish_migration/utils/utils.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index e40dc339b2..fb909f1b83 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -13,6 +13,7 @@ import ( "golang.org/x/exp/maps" "github.com/tidepool-org/platform/data" + "github.com/tidepool-org/platform/structure" "github.com/tidepool-org/platform/data/deduplicator/deduplicator" "github.com/tidepool-org/platform/data/types" @@ -161,10 +162,10 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { //cleanup //incomingKeys := maps.Keys(ojbData) - unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "_schemaVersion"} - for _, unparsed := range unparsedFields { - delete(ojbData, unparsed) - } + // unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "_schemaVersion", "uploadId", "guid", "createdTime", "modifiedTime", "deviceTime"} + // for _, unparsed := range unparsedFields { + // delete(ojbData, unparsed) + // } cleanedKeys := maps.Keys(ojbData) cleanedJSONData, err := json.Marshal(ojbData) @@ -173,8 +174,8 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { } //parsing - parser := structureParser.NewObject(&ojbData) - validator := structureValidator.New() + parser := structureParser.NewObject(&ojbData).WithOrigin(structure.OriginStore) + validator := structureValidator.New().WithOrigin(structure.OriginStore) normalizer := dataNormalizer.New() datum := dataTypesFactory.ParseDatum(parser) @@ -188,7 +189,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { parser.NotParsed() if err := parser.Error(); err != nil { - return nil, errorsP.Wrap(err, fmt.Sprintf("type[%s] cleaned[%s]", dType, cleanedKeys)) + return nil, errorsP.Wrap(err, fmt.Sprintf("type[%s] parsing datum keys%s", dType, cleanedKeys)) } if err := validator.Error(); err != nil { From 573afd873caf838703cdd93241d622e14263d5bb Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 1 Feb 2024 11:34:02 +1300 Subject: [PATCH 167/413] unparsed fields --- migrations/20231128_jellyfish_migration/utils/utils.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index fb909f1b83..bc84861d36 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -162,10 +162,10 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { //cleanup //incomingKeys := maps.Keys(ojbData) - // unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "_schemaVersion", "uploadId", "guid", "createdTime", "modifiedTime", "deviceTime"} - // for _, unparsed := range unparsedFields { - // delete(ojbData, unparsed) - // } + unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "_schemaVersion", "uploadId", "guid", "createdTime", "modifiedTime", "deviceTime", "time"} + for _, unparsed := range unparsedFields { + delete(ojbData, unparsed) + } cleanedKeys := maps.Keys(ojbData) cleanedJSONData, err := json.Marshal(ojbData) From 45e0cca82cdd4f60c00c93f35c7d717a852d8e36 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 1 Feb 2024 11:39:54 +1300 Subject: [PATCH 168/413] internal origin --- migrations/20231128_jellyfish_migration/utils/utils.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index bc84861d36..99c6218ce1 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -174,8 +174,8 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { } //parsing - parser := structureParser.NewObject(&ojbData).WithOrigin(structure.OriginStore) - validator := structureValidator.New().WithOrigin(structure.OriginStore) + parser := structureParser.NewObject(&ojbData).WithOrigin(structure.OriginInternal) + validator := structureValidator.New().WithOrigin(structure.OriginInternal) normalizer := dataNormalizer.New() datum := dataTypesFactory.ParseDatum(parser) From d8304b0c0e04e762b7c595b441ab4182e0b0bffc Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 1 Feb 2024 11:47:03 +1300 Subject: [PATCH 169/413] no origin --- migrations/20231128_jellyfish_migration/utils/utils.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 99c6218ce1..6e1b4ccf88 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -13,7 +13,6 @@ import ( "golang.org/x/exp/maps" "github.com/tidepool-org/platform/data" - "github.com/tidepool-org/platform/structure" "github.com/tidepool-org/platform/data/deduplicator/deduplicator" "github.com/tidepool-org/platform/data/types" @@ -174,8 +173,8 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { } //parsing - parser := structureParser.NewObject(&ojbData).WithOrigin(structure.OriginInternal) - validator := structureValidator.New().WithOrigin(structure.OriginInternal) + parser := structureParser.NewObject(&ojbData) + validator := structureValidator.New() normalizer := dataNormalizer.New() datum := dataTypesFactory.ParseDatum(parser) From af34ee3469063aa6442ee64ad65ace7d1d210723 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 1 Feb 2024 12:01:33 +1300 Subject: [PATCH 170/413] error context --- migrations/20231128_jellyfish_migration/utils/utils.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 6e1b4ccf88..1c7849e191 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -161,7 +161,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { //cleanup //incomingKeys := maps.Keys(ojbData) - unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "_schemaVersion", "uploadId", "guid", "createdTime", "modifiedTime", "deviceTime", "time"} + unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "_schemaVersion", "uploadId", "guid", "createdTime", "modifiedTime"} for _, unparsed := range unparsedFields { delete(ojbData, unparsed) } @@ -188,15 +188,15 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { parser.NotParsed() if err := parser.Error(); err != nil { - return nil, errorsP.Wrap(err, fmt.Sprintf("type[%s] parsing datum keys%s", dType, cleanedKeys)) + return nil, errorsP.Wrap(err, fmt.Sprintf("parsing type[%s] with keys%s", dType, cleanedKeys)) } if err := validator.Error(); err != nil { - return nil, err + return nil, errorsP.Wrap(err, fmt.Sprintf("validate type[%s] with keys%s", dType, cleanedKeys)) } if err := normalizer.Error(); err != nil { - return nil, err + return nil, errorsP.Wrap(err, fmt.Sprintf("normalize type[%s] with keys%s", dType, cleanedKeys)) } outgoingJSONData, err := json.Marshal(datum) From 3a6e69358689b77775e5aa3968d5478d44c72025 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 1 Feb 2024 14:36:37 +1300 Subject: [PATCH 171/413] errs --- .../utils/migrationUtil.go | 9 ++- .../utils/test/data.go | 72 +++++++++++++++++++ .../utils/utils.go | 34 +++++---- 3 files changed, 100 insertions(+), 15 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 62944bae42..15a9809034 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -228,7 +228,14 @@ func (m *migrationUtil) OnError(reportErr error, id string, msg string) { os.Exit(1) } defer f.Close() - f.WriteString(fmt.Sprintf(errFormat, id, msg, reportErr.Error())) + + errBytes, err := bson.Marshal(reportErr) + if err != nil { + log.Println(err) + os.Exit(1) + } + + f.WriteString(fmt.Sprintf(errFormat, id, msg, string(errBytes))) if m.config.stopOnErr { log.Printf(errFormat, id, msg, reportErr.Error()) os.Exit(1) diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go index 1fd8ce88d2..fa6108e845 100644 --- a/migrations/20231128_jellyfish_migration/utils/test/data.go +++ b/migrations/20231128_jellyfish_migration/utils/test/data.go @@ -153,7 +153,79 @@ func omnipodPumpSettingsDatum() map[string]interface{} { return datum } +func tandemAutomatedBasalDatum() map[string]interface{} { + datum := base("tandemCIQ1111111111111") + datum["type"] = "basal" + datum["deliveryType"] = "automated" + datum["timezoneOffset"] = -300 + datum["clockDriftOffset"] = -137000 + datum["conversionOffset"] = 0 + datum["duration"] = 300000 + datum["rate"] = 0.335 + datum["percent"] = 0.47857142857142865 + datum["conversionOffset"] = 0 + datum["suppressed"] = map[string]interface{}{ + "type": "basal", + "deliveryType": "scheduled", + "rate": 0.7, + } + return datum +} + +func tandemWizardDatum() map[string]interface{} { + datum := base("tandemCIQ1111111111111") + datum["type"] = "wizard" + + datum["timezoneOffset"] = -300 + datum["clockDriftOffset"] = -221000 + datum["conversionOffset"] = 0 + datum["recommended"] = map[string]interface{}{ + "carb": 2, + "deliveryType": "scheduled", + "rate": 0.7, + } + + datum["duration"] = 300000 + datum["rate"] = 0.335 + datum["percent"] = 0.47857142857142865 + datum["conversionOffset"] = 0 + + return datum + + /* + {"_id":"00006uv9j2d38nnf90p3945uaur4p14v", + "time":{"$date":{"$numberLong":"1682144172000"}}, + "timezoneOffset":{"$numberInt":"-300"}, + "clockDriftOffset":{"$numberInt":"-221000"}, + "conversionOffset":{"$numberInt":"0"}, + "deviceTime":"2023-04-22T01:16:12", + "deviceId":"tandemCIQ1000096506889","type":"wizard", + "recommended":{"carb":{"$numberInt":"2"},"correction":{"$numberDouble":"0.35"},"net":{"$numberDouble":"2.35"}}, + "bgInput":{"$numberDouble":"8.603659386120578"}, + "carbInput":{"$numberInt":"20"}, + "insulinOnBoard":{"$numberInt":"0"}, + "insulinCarbRatio":{"$numberInt":"0"}, + "insulinSensitivity":{"$numberInt":"0"}, + "bgTarget":{"target":{"$numberInt":"0"}}, + "bolus":"sh3j1i31f7jsvjfomuaen7s18a7f7s46", + "units":"mmol/L", + "payload":{"logIndices":[{"$numberInt":"66177"}]}, + "uploadId":"upid_7af862c1228c", + "guid":"0662f529-989a-471f-8fe3-06d601ac6a0c", + "_userId":"23ea008b-4d69-4a10-9dd5-9505b0ec1f24", + "_groupId":"7c23d7dc18", + "id":"dfgjgrs9j9av9sfd6huvilqcejr6f2uv", + "modifiedTime":{"$date":{"$numberLong":"1691609596487"}}, + "createdTime":{"$date":{"$numberLong":"1691609596487"}}, + "_version":{"$numberInt":"0"}, + "_active":true, + "_deduplicator":{"hash":"xIVlJ3lN3+f1qzYDm/2+4eHWD9MODiN0JbmanvN1wO4="}} + */ +} + var CBGDexcomG5MobDatum = dexG5MobDatum() var PumpSettingsTandem = tandemPumpSettingsDatum() var PumpSettingsCarelink = carelinkPumpSettings() var PumpSettingsOmnipod = omnipodPumpSettingsDatum() +var AutomatedBasalTandem = tandemAutomatedBasalDatum() +var WizardTandem = tandemWizardDatum() diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 1c7849e191..21a7da050d 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -10,7 +10,6 @@ import ( "github.com/r3labs/diff/v3" "go.mongodb.org/mongo-driver/bson" - "golang.org/x/exp/maps" "github.com/tidepool-org/platform/data" @@ -161,16 +160,16 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { //cleanup //incomingKeys := maps.Keys(ojbData) - unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "_schemaVersion", "uploadId", "guid", "createdTime", "modifiedTime"} - for _, unparsed := range unparsedFields { - delete(ojbData, unparsed) - } - cleanedKeys := maps.Keys(ojbData) + // unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "_schemaVersion", "uploadId", "guid", "createdTime", "modifiedTime"} + // for _, unparsed := range unparsedFields { + // delete(ojbData, unparsed) + // } + // cleanedKeys := maps.Keys(ojbData) - cleanedJSONData, err := json.Marshal(ojbData) - if err != nil { - return nil, err - } + // cleanedJSONData, err := json.Marshal(ojbData) + // if err != nil { + // return nil, err + // } //parsing parser := structureParser.NewObject(&ojbData) @@ -184,19 +183,26 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { } else { return nil, errorsP.Newf("no datum returned for id=[%s]", dID) } + // here + + // validator.Bool("_active", parser.Bool("_active")).Exists() + // validator.String("_groupId", parser.String("_groupId")).Exists() + // validator.String("_id", parser.String("_id")).Exists() + // validator.String("_userId", parser.String("_userId")).Exists() + // validator.Int("_version", parser.Int("_version")).Exists() parser.NotParsed() if err := parser.Error(); err != nil { - return nil, errorsP.Wrap(err, fmt.Sprintf("parsing type[%s] with keys%s", dType, cleanedKeys)) + return nil, err //errorsP.Wrap(err, fmt.Sprintf("parsing type[%s] with keys%s", dType, cleanedKeys)) } if err := validator.Error(); err != nil { - return nil, errorsP.Wrap(err, fmt.Sprintf("validate type[%s] with keys%s", dType, cleanedKeys)) + return nil, err // errorsP.Wrap(err, fmt.Sprintf("validate type[%s] with keys%s", dType, cleanedKeys)) } if err := normalizer.Error(); err != nil { - return nil, errorsP.Wrap(err, fmt.Sprintf("normalize type[%s] with keys%s", dType, cleanedKeys)) + return nil, err //errorsP.Wrap(err, fmt.Sprintf("normalize type[%s] with keys%s", dType, cleanedKeys)) } outgoingJSONData, err := json.Marshal(datum) @@ -212,7 +218,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { changelog, _ := diff.Diff(ojbData, processedData, diff.StructMapKeySupport()) logDiff(dID, changelog) - logBeforeAndAfter(dID, cleanedJSONData, outgoingJSONData) + //logBeforeAndAfter(dID, cleanedJSONData, outgoingJSONData) return *datum, nil } From 109f6a472718b8b43d31f4fa6ff1234f6bb4721d Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 1 Feb 2024 15:08:28 +1300 Subject: [PATCH 172/413] json errors --- .../utils/migrationUtil.go | 6 ++- .../utils/utils.go | 43 +++++++++++-------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 15a9809034..ad03a4a14e 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -2,6 +2,7 @@ package utils import ( "context" + "encoding/json" "errors" "fmt" "log" @@ -229,13 +230,14 @@ func (m *migrationUtil) OnError(reportErr error, id string, msg string) { } defer f.Close() - errBytes, err := bson.Marshal(reportErr) + errBytes, err := json.Marshal(reportErr) if err != nil { log.Println(err) os.Exit(1) } - f.WriteString(fmt.Sprintf(errFormat, id, msg, string(errBytes))) + f.WriteString(fmt.Sprintf("[_id=%s]\n", id)) + f.WriteString(string(errBytes)) if m.config.stopOnErr { log.Printf(errFormat, id, msg, reportErr.Error()) os.Exit(1) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 21a7da050d..f84cb73e12 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -7,6 +7,7 @@ import ( "os" "slices" "strings" + "time" "github.com/r3labs/diff/v3" "go.mongodb.org/mongo-driver/bson" @@ -88,16 +89,16 @@ func logDiff(id string, updates interface{}) { f.WriteString(fmt.Sprintf(`{"_id":"%s","diff":%s},`, id, string(updatesJSON))) } -func logBeforeAndAfter(id string, original []byte, updated []byte) { - f, err := os.OpenFile("changes.log", - os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - log.Println(err) - os.Exit(1) - } - defer f.Close() - f.WriteString(fmt.Sprintf(`{"_id":"%s","jellyfish":%s,"platform":%s},`, id, string(original), string(updated))) -} +// func logBeforeAndAfter(id string, original []byte, updated []byte) { +// f, err := os.OpenFile("changes.log", +// os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) +// if err != nil { +// log.Println(err) +// os.Exit(1) +// } +// defer f.Close() +// f.WriteString(fmt.Sprintf(`{"_id":"%s","jellyfish":%s,"platform":%s},`, id, string(original), string(updated))) +// } func ProcessDatum(bsonData bson.M) (data.Datum, error) { @@ -183,26 +184,30 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { } else { return nil, errorsP.Newf("no datum returned for id=[%s]", dID) } - // here - // validator.Bool("_active", parser.Bool("_active")).Exists() - // validator.String("_groupId", parser.String("_groupId")).Exists() - // validator.String("_id", parser.String("_id")).Exists() - // validator.String("_userId", parser.String("_userId")).Exists() - // validator.Int("_version", parser.Int("_version")).Exists() + validator.Bool("_active", parser.Bool("_active")).Exists() + validator.String("_groupId", parser.String("_groupId")).Exists() + validator.String("_id", parser.String("_id")).Exists() + validator.String("_userId", parser.String("_userId")).Exists() + validator.Int("_version", parser.Int("_version")).Exists() + validator.Object("_deduplicator", parser.Object("_deduplicator")).Exists() + validator.String("uploadId", parser.String("uploadId")).Exists() + validator.String("guid", parser.String("guid")).Exists() + validator.Time("createdTime", parser.Time("createdTime", time.RFC3339Nano)).Exists() + validator.Time("modifiedTime", parser.Time("modifiedTime", time.RFC3339Nano)) parser.NotParsed() if err := parser.Error(); err != nil { - return nil, err //errorsP.Wrap(err, fmt.Sprintf("parsing type[%s] with keys%s", dType, cleanedKeys)) + return nil, err } if err := validator.Error(); err != nil { - return nil, err // errorsP.Wrap(err, fmt.Sprintf("validate type[%s] with keys%s", dType, cleanedKeys)) + return nil, err } if err := normalizer.Error(); err != nil { - return nil, err //errorsP.Wrap(err, fmt.Sprintf("normalize type[%s] with keys%s", dType, cleanedKeys)) + return nil, err } outgoingJSONData, err := json.Marshal(datum) From 9b07737ce9fadeb5682e2833b63e91bf7ec9dc30 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 1 Feb 2024 15:24:05 +1300 Subject: [PATCH 173/413] parse _schemaVersion --- .../utils/migrationUtil.go | 4 +--- .../20231128_jellyfish_migration/utils/utils.go | 12 +----------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index ad03a4a14e..37626cdde2 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -235,9 +235,7 @@ func (m *migrationUtil) OnError(reportErr error, id string, msg string) { log.Println(err) os.Exit(1) } - - f.WriteString(fmt.Sprintf("[_id=%s]\n", id)) - f.WriteString(string(errBytes)) + f.WriteString(fmt.Sprintf("[_id=%s] %s\n", id, string(errBytes))) if m.config.stopOnErr { log.Printf(errFormat, id, msg, reportErr.Error()) os.Exit(1) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index f84cb73e12..786f4cfc02 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -89,17 +89,6 @@ func logDiff(id string, updates interface{}) { f.WriteString(fmt.Sprintf(`{"_id":"%s","diff":%s},`, id, string(updatesJSON))) } -// func logBeforeAndAfter(id string, original []byte, updated []byte) { -// f, err := os.OpenFile("changes.log", -// os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) -// if err != nil { -// log.Println(err) -// os.Exit(1) -// } -// defer f.Close() -// f.WriteString(fmt.Sprintf(`{"_id":"%s","jellyfish":%s,"platform":%s},`, id, string(original), string(updated))) -// } - func ProcessDatum(bsonData bson.M) (data.Datum, error) { dType := fmt.Sprintf("%v", bsonData["type"]) @@ -190,6 +179,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { validator.String("_id", parser.String("_id")).Exists() validator.String("_userId", parser.String("_userId")).Exists() validator.Int("_version", parser.Int("_version")).Exists() + validator.Int("_schemaVersion", parser.Int("_schemaVersion")) validator.Object("_deduplicator", parser.Object("_deduplicator")).Exists() validator.String("uploadId", parser.String("uploadId")).Exists() validator.String("guid", parser.String("guid")).Exists() From ed17d493e21e8b5ea9f92f6da494bac1f902498c Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 1 Feb 2024 15:37:10 +1300 Subject: [PATCH 174/413] cleanup for processed data --- migrations/20231128_jellyfish_migration/utils/utils.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 786f4cfc02..f0cf4d00fa 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -181,6 +181,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { validator.Int("_version", parser.Int("_version")).Exists() validator.Int("_schemaVersion", parser.Int("_schemaVersion")) validator.Object("_deduplicator", parser.Object("_deduplicator")).Exists() + validator.String("uploadId", parser.String("uploadId")).Exists() validator.String("guid", parser.String("guid")).Exists() validator.Time("createdTime", parser.Time("createdTime", time.RFC3339Nano)).Exists() @@ -210,11 +211,15 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { return nil, err } + // these are extras that we want to leave on the original object + notRequired := []string{"_active", "_groupId", "_id", "_userId", "_version", "_schemaVersion", "_deduplicator"} + for _, key := range notRequired { + delete(processedData, key) + } + changelog, _ := diff.Diff(ojbData, processedData, diff.StructMapKeySupport()) logDiff(dID, changelog) - //logBeforeAndAfter(dID, cleanedJSONData, outgoingJSONData) - return *datum, nil } From c33568011cb4408aeb01912268a8dbb33067b898 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 1 Feb 2024 15:50:14 +1300 Subject: [PATCH 175/413] cleanup, errs --- .../jellyfish_migration.go | 2 +- .../utils/migrationUtil.go | 2 +- .../utils/utils.go | 18 ++---------------- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 2a49d495fe..7fd5122bdc 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -319,7 +319,7 @@ func (m *Migration) fetchAndProcess() bool { } _, err := utils.ProcessDatum(item) if err != nil { - m.migrationUtil.OnError(err, fmt.Sprintf("%v", item["_id"]), "processing") + m.migrationUtil.OnError(err, fmt.Sprintf("%v", item["_id"]), fmt.Sprintf("[type=%v]", item["type"])) } all = append(all, item) } diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 37626cdde2..8cb6ce752e 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -235,7 +235,7 @@ func (m *migrationUtil) OnError(reportErr error, id string, msg string) { log.Println(err) os.Exit(1) } - f.WriteString(fmt.Sprintf("[_id=%s] %s\n", id, string(errBytes))) + f.WriteString(fmt.Sprintf("[_id=%s] %s %s\n", id, msg, string(errBytes))) if m.config.stopOnErr { log.Printf(errFormat, id, msg, reportErr.Error()) os.Exit(1) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index f0cf4d00fa..c199810896 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -148,19 +148,6 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { return nil, err } - //cleanup - //incomingKeys := maps.Keys(ojbData) - // unparsedFields := []string{"_deduplicator", "_groupId", "_active", "_version", "_userId", "_id", "_schemaVersion", "uploadId", "guid", "createdTime", "modifiedTime"} - // for _, unparsed := range unparsedFields { - // delete(ojbData, unparsed) - // } - // cleanedKeys := maps.Keys(ojbData) - - // cleanedJSONData, err := json.Marshal(ojbData) - // if err != nil { - // return nil, err - // } - //parsing parser := structureParser.NewObject(&ojbData) validator := structureValidator.New() @@ -181,7 +168,6 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { validator.Int("_version", parser.Int("_version")).Exists() validator.Int("_schemaVersion", parser.Int("_schemaVersion")) validator.Object("_deduplicator", parser.Object("_deduplicator")).Exists() - validator.String("uploadId", parser.String("uploadId")).Exists() validator.String("guid", parser.String("guid")).Exists() validator.Time("createdTime", parser.Time("createdTime", time.RFC3339Nano)).Exists() @@ -212,9 +198,9 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { } // these are extras that we want to leave on the original object - notRequired := []string{"_active", "_groupId", "_id", "_userId", "_version", "_schemaVersion", "_deduplicator"} + notRequired := []string{"_active", "_groupId", "_id", "_userId", "_version", "_schemaVersion", "_deduplicator", "uploadId"} for _, key := range notRequired { - delete(processedData, key) + delete(ojbData, key) } changelog, _ := diff.Diff(ojbData, processedData, diff.StructMapKeySupport()) From 3ef6df2dce2398618246e9642947b08c42049465 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 1 Feb 2024 16:09:05 +1300 Subject: [PATCH 176/413] diff logging --- .../utils/utils.go | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index c199810896..238533e6d6 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -78,15 +78,17 @@ func pumpSettingsHasBolus(bsonData bson.M) bool { } func logDiff(id string, updates interface{}) { - f, err := os.OpenFile("diff.log", - os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - log.Println(err) - os.Exit(1) - } - defer f.Close() updatesJSON, _ := json.Marshal(updates) - f.WriteString(fmt.Sprintf(`{"_id":"%s","diff":%s},`, id, string(updatesJSON))) + if string(updatesJSON) != "[]" { + f, err := os.OpenFile("diff.log", + os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Println(err) + os.Exit(1) + } + defer f.Close() + f.WriteString(fmt.Sprintf(`{"_id":"%s","diff":%s},`, id, string(updatesJSON))) + } } func ProcessDatum(bsonData bson.M) (data.Datum, error) { @@ -198,7 +200,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { } // these are extras that we want to leave on the original object - notRequired := []string{"_active", "_groupId", "_id", "_userId", "_version", "_schemaVersion", "_deduplicator", "uploadId"} + notRequired := []string{"_active", "_groupId", "_id", "_userId", "_version", "_schemaVersion", "_deduplicator", "uploadId", "createdTime", "guid", "modifiedTime"} for _, key := range notRequired { delete(ojbData, key) } From 8b00d0f6c68381e2c7ef2ae5377f48dbe42dccbc Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 1 Feb 2024 16:56:07 +1300 Subject: [PATCH 177/413] cleanup --- migrations/20231128_jellyfish_migration/utils/utils.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 238533e6d6..09765b3a64 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -169,9 +169,12 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { validator.String("_userId", parser.String("_userId")).Exists() validator.Int("_version", parser.Int("_version")).Exists() validator.Int("_schemaVersion", parser.Int("_schemaVersion")) + + validator.Int("_archivedTime", parser.Int("_archivedTime")) validator.Object("_deduplicator", parser.Object("_deduplicator")).Exists() + validator.String("uploadId", parser.String("uploadId")).Exists() - validator.String("guid", parser.String("guid")).Exists() + validator.String("guid", parser.String("guid")) validator.Time("createdTime", parser.Time("createdTime", time.RFC3339Nano)).Exists() validator.Time("modifiedTime", parser.Time("modifiedTime", time.RFC3339Nano)) @@ -200,7 +203,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { } // these are extras that we want to leave on the original object - notRequired := []string{"_active", "_groupId", "_id", "_userId", "_version", "_schemaVersion", "_deduplicator", "uploadId", "createdTime", "guid", "modifiedTime"} + notRequired := []string{"_active", "_groupId", "_id", "_userId", "_version", "_schemaVersion", "_deduplicator", "uploadId", "createdTime", "guid", "modifiedTime", "_archivedTime"} for _, key := range notRequired { delete(ojbData, key) } From 235c05c524fbf1c89d7fc25901d1d2fc0c617f15 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 1 Feb 2024 17:09:19 +1300 Subject: [PATCH 178/413] fix type --- migrations/20231128_jellyfish_migration/utils/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 09765b3a64..92e40f8e8b 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -170,7 +170,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { validator.Int("_version", parser.Int("_version")).Exists() validator.Int("_schemaVersion", parser.Int("_schemaVersion")) - validator.Int("_archivedTime", parser.Int("_archivedTime")) + validator.String("_archivedTime", parser.String("_archivedTime")) validator.Object("_deduplicator", parser.Object("_deduplicator")).Exists() validator.String("uploadId", parser.String("uploadId")).Exists() From fc353cbc28342700ef1e718772253346d366dc20 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 7 Feb 2024 21:37:23 +1300 Subject: [PATCH 179/413] BACK 2746 --- data/blood/glucose/glucose.go | 14 ------------ .../device/override/settings/pump/pump.go | 6 ++--- .../override/settings/pump/pump_test.go | 22 +++++++++---------- 3 files changed, 14 insertions(+), 28 deletions(-) diff --git a/data/blood/glucose/glucose.go b/data/blood/glucose/glucose.go index 791bdae799..32ca889dd9 100644 --- a/data/blood/glucose/glucose.go +++ b/data/blood/glucose/glucose.go @@ -63,20 +63,6 @@ func NormalizeValueForUnits(value *float64, units *string) *float64 { intValue := int(*value/MmolLToMgdLConversionFactor*MmolLToMgdLPrecisionFactor + 0.5) floatValue := float64(intValue) / MmolLToMgdLPrecisionFactor return &floatValue - - case MmolL, Mmoll: - - mgdlVal := *value * MmolLToMgdLConversionFactor - - intValue := int(mgdlVal/MmolLToMgdLConversionFactor*MmolLToMgdLPrecisionFactor + 0.5) - floatValue := float64(intValue) / MmolLToMgdLPrecisionFactor - return &floatValue - - //if len([]rune(strVal)) > 8 { - // floatValue := math.Floor(*value*MmolLToMgdLPrecisionFactor) / MmolLToMgdLPrecisionFactor - // return &floatValue - //} - //return value } } return value diff --git a/data/types/device/override/settings/pump/pump.go b/data/types/device/override/settings/pump/pump.go index 21ad0bd430..7b9d42063c 100644 --- a/data/types/device/override/settings/pump/pump.go +++ b/data/types/device/override/settings/pump/pump.go @@ -132,9 +132,9 @@ func (p *Pump) Validate(validator structure.Validator) { unitsValidator.ReportError(structureValidator.ErrorValueNotExists()) } - if p.BloodGlucoseTarget == nil && p.BasalRateScaleFactor == nil && p.CarbohydrateRatioScaleFactor == nil && p.InsulinSensitivityScaleFactor == nil { - validator.ReportError(structureValidator.ErrorValuesNotExistForAny("bgTarget", "basalRateScaleFactor", "carbRatioScaleFactor", "insulinSensitivityScaleFactor")) - } + // if p.BloodGlucoseTarget == nil && p.BasalRateScaleFactor == nil && p.CarbohydrateRatioScaleFactor == nil && p.InsulinSensitivityScaleFactor == nil { + // validator.ReportError(structureValidator.ErrorValuesNotExistForAny("bgTarget", "basalRateScaleFactor", "carbRatioScaleFactor", "insulinSensitivityScaleFactor")) + // } } func (p *Pump) Normalize(normalizer data.Normalizer) { diff --git a/data/types/device/override/settings/pump/pump_test.go b/data/types/device/override/settings/pump/pump_test.go index ff3a05e97f..e94e2d5e69 100644 --- a/data/types/device/override/settings/pump/pump_test.go +++ b/data/types/device/override/settings/pump/pump_test.go @@ -679,17 +679,17 @@ var _ = Describe("Pump", func() { datum.BloodGlucoseTarget = dataBloodGlucoseTest.RandomTarget(unitsBloodGlucose) }, ), - Entry("one of required missing", - pointer.FromString("mmol/L"), - func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { - datum.BloodGlucoseTarget = nil - datum.BasalRateScaleFactor = nil - datum.CarbohydrateRatioScaleFactor = nil - datum.InsulinSensitivityScaleFactor = nil - datum.Units = nil - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValuesNotExistForAny("bgTarget", "basalRateScaleFactor", "carbRatioScaleFactor", "insulinSensitivityScaleFactor"), "", NewMeta()), - ), + // Entry("one of required missing", + // pointer.FromString("mmol/L"), + // func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { + // datum.BloodGlucoseTarget = nil + // datum.BasalRateScaleFactor = nil + // datum.CarbohydrateRatioScaleFactor = nil + // datum.InsulinSensitivityScaleFactor = nil + // datum.Units = nil + // }, + // errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValuesNotExistForAny("bgTarget", "basalRateScaleFactor", "carbRatioScaleFactor", "insulinSensitivityScaleFactor"), "", NewMeta()), + // ), Entry("multiple errors", pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { From 0e6783e26b015dfff43f1d1158bae57b33bbcf7a Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 7 Feb 2024 22:04:49 +1300 Subject: [PATCH 180/413] tests moves to migration utils --- data/blood/glucose/glucose_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/data/blood/glucose/glucose_test.go b/data/blood/glucose/glucose_test.go index 39940c5f95..cf726fd967 100644 --- a/data/blood/glucose/glucose_test.go +++ b/data/blood/glucose/glucose_test.go @@ -107,7 +107,6 @@ var _ = Describe("Glucose", func() { Entry("returns unchanged value for mmol/l units", pointer.FromFloat64(10.0), pointer.FromString("mmol/l"), pointer.FromFloat64(10.0)), Entry("returns converted value for mg/dL units", pointer.FromFloat64(180.0), pointer.FromString("mg/dL"), pointer.FromFloat64(9.99135)), Entry("returns converted value for mg/dl units", pointer.FromFloat64(180.0), pointer.FromString("mg/dl"), pointer.FromFloat64(9.99135)), - Entry("returns converted value for mmol/L units with incorrect precision", pointer.FromFloat64(4.88465823212007), pointer.FromString("mmol/L"), pointer.FromFloat64(4.88466)), ) It("properly normalizes a range of mmol/L values", func() { From 2d2ecb56e7502d1dc06c24b09278b795d4f48d47 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 7 Feb 2024 22:51:08 +1300 Subject: [PATCH 181/413] basic update tests --- .../utils/utils.go | 120 +++++++++++++++--- .../utils/utils_test.go | 103 +++++++++++++++ 2 files changed, 206 insertions(+), 17 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 92e40f8e8b..3a70279a57 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -14,6 +14,7 @@ import ( "github.com/tidepool-org/platform/data" + "github.com/tidepool-org/platform/data/blood/glucose" "github.com/tidepool-org/platform/data/deduplicator/deduplicator" "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/data/types/basal" @@ -91,38 +92,49 @@ func logDiff(id string, updates interface{}) { } } -func ProcessDatum(bsonData bson.M) (data.Datum, error) { - +func ApplyBaseChanges(bsonData bson.M) error { dType := fmt.Sprintf("%v", bsonData["type"]) - dID := fmt.Sprintf("%v", bsonData["_id"]) - switch dType { case pump.Type: if boluses := bsonData["bolus"]; boluses != nil { bsonData["boluses"] = boluses + //TODO delete from mongo delete(bsonData, "bolus") } - // case selfmonitored.Type, ketone.Type, continuous.Type: - // units := fmt.Sprintf("%v", bsonData["units"]) - // if units == glucose.MmolL || units == glucose.Mmoll { - - // if val, ok := bsonData["value"].(float64); ok { - - // } - - // } + case selfmonitored.Type, ketone.Type, continuous.Type: + units := fmt.Sprintf("%v", bsonData["units"]) + if units == glucose.MmolL || units == glucose.Mmoll { + floatStr := fmt.Sprintf("%v", bsonData["value"]) + floatParts := strings.Split(floatStr, ".") + if len(floatParts) == 2 { + if len(floatParts[1]) > 5 { + //TODO update in mongo + if floatVal, ok := bsonData["value"].(float64); ok { + mgdlVal := floatVal * glucose.MmolLToMgdLConversionFactor + intValue := int(mgdlVal/glucose.MmolLToMgdLConversionFactor*glucose.MmolLToMgdLPrecisionFactor + 0.5) + floatValue := float64(intValue) / glucose.MmolLToMgdLPrecisionFactor + bsonData["value"] = floatValue + } + } + } + } + case basal.Type: + if percent := bsonData["percent"]; percent != nil { + //TODO delete from mongo + delete(bsonData, "percent") + } } if payload := bsonData["payload"]; payload != nil { if _, ok := payload.(string); ok { dataBytes, err := bson.Marshal(payload) if err != nil { - return nil, err + return err } var payloadMetadata metadata.Metadata err = bson.Unmarshal(dataBytes, &payloadMetadata) if err != nil { - return nil, errorsP.Newf("payload could not be set from %v ", string(dataBytes)) + return errorsP.Newf("payload could not be set from %v ", string(dataBytes)) } bsonData["payload"] = &payloadMetadata } @@ -131,15 +143,85 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { if _, ok := annotations.(string); ok { dataBytes, err := bson.Marshal(annotations) if err != nil { - return nil, err + return err } var metadataArray metadata.MetadataArray if err := bson.Unmarshal(dataBytes, &metadataArray); err != nil { - return nil, errorsP.Newf("annotations could not be set from %v ", string(dataBytes)) + return errorsP.Newf("annotations could not be set from %v ", string(dataBytes)) } bsonData["annotations"] = &metadataArray } } + return nil +} + +func ProcessDatum(bsonData bson.M) (data.Datum, error) { + + dID := fmt.Sprintf("%v", bsonData["_id"]) + + if err := ApplyBaseChanges(bsonData); err != nil { + return nil, err + } + + // switch dType { + // case pump.Type: + // if boluses := bsonData["bolus"]; boluses != nil { + // bsonData["boluses"] = boluses + // //TODO delete from mongo + // delete(bsonData, "bolus") + // } + // //TODO Entry("returns converted value for mmol/L units with incorrect precision", pointer.FromFloat64(4.88465823212007), pointer.FromString("mmol/L"), pointer.FromFloat64(4.88466)), + // // case selfmonitored.Type, ketone.Type, continuous.Type: + // // units := fmt.Sprintf("%v", bsonData["units"]) + // // if units == glucose.MmolL || units == glucose.Mmoll { + // // floatStr := fmt.Sprintf("%v", bsonData["value"]) + // // floatParts := strings.Split(floatStr, ".") + // // if len(floatParts) == 2 { + // // if len(floatParts[1]) > 5 { + // // //TODO update in mongo + // // if floatVal, ok := bsonData["value"].(float64); ok { + // // mgdlVal := floatVal * glucose.MmolLToMgdLConversionFactor + // // intValue := int(mgdlVal/glucose.MmolLToMgdLConversionFactor*glucose.MmolLToMgdLPrecisionFactor + 0.5) + // // floatValue := float64(intValue) / glucose.MmolLToMgdLPrecisionFactor + // // bsonData["value"] = floatValue + // // } + // // } + // // } + // // } + // case basal.Type: + // if percent := bsonData["percent"]; percent != nil { + // //TODO delete from mongo + // delete(bsonData, "percent") + // } + // } + + // if payload := bsonData["payload"]; payload != nil { + // if _, ok := payload.(string); ok { + // dataBytes, err := bson.Marshal(payload) + // if err != nil { + // return nil, err + // } + // var payloadMetadata metadata.Metadata + // err = bson.Unmarshal(dataBytes, &payloadMetadata) + // if err != nil { + // return nil, errorsP.Newf("payload could not be set from %v ", string(dataBytes)) + // } + // bsonData["payload"] = &payloadMetadata + // } + // } + // if annotations := bsonData["annotations"]; annotations != nil { + // if _, ok := annotations.(string); ok { + // dataBytes, err := bson.Marshal(annotations) + // if err != nil { + // return nil, err + // } + // var metadataArray metadata.MetadataArray + // if err := bson.Unmarshal(dataBytes, &metadataArray); err != nil { + // return nil, errorsP.Newf("annotations could not be set from %v ", string(dataBytes)) + // } + // bsonData["annotations"] = &metadataArray + // } + // } incomingJSONData, err := json.Marshal(bsonData) if err != nil { @@ -159,6 +241,10 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { if datum != nil && *datum != nil { (*datum).Validate(validator) (*datum).Normalize(normalizer) + + // if (*datum).GetType() == selfmonitored.Type { + // //TODO + // } } else { return nil, errorsP.Newf("no datum returned for id=[%s]", dID) } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 2b5eab8293..3e057eafc5 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -23,6 +23,109 @@ import ( var _ = Describe("back-37", func() { var _ = Describe("utils", func() { + var _ = Describe("ApplyBaseChanges", func() { + + const expectedID = "some-id" + + var getBSONData = func(datum interface{}) bson.M { + var bsonData bson.M + bsonAsByte, _ := bson.Marshal(&datum) + bson.Unmarshal(bsonAsByte, &bsonData) + return bsonData + } + + Context("pumpSettings", func() { + + var pumpSettingsDatum *pump.Pump + var settingsBolusDatum bson.M + + BeforeEach(func() { + mmolL := pump.DisplayBloodGlucoseUnitsMmolPerL + pumpSettingsDatum = pumpTest.NewPump(&mmolL) + *pumpSettingsDatum.ID = expectedID + *pumpSettingsDatum.UserID = "some-user-id" + *pumpSettingsDatum.DeviceID = "some-device-id" + theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") + *pumpSettingsDatum.Time = theTime + var bolusData = &pump.BolusMap{ + "bolus-1": pumpTest.NewRandomBolus(), + "bolus-2": pumpTest.NewRandomBolus(), + } + settingsBolusDatum = getBSONData(pumpSettingsDatum) + settingsBolusDatum["bolus"] = bolusData + settingsBolusDatum["_id"] = expectedID + }) + + Context("with mis-named jellyfish bolus", func() { + var bolusData = &pump.BolusMap{ + "bolus-1": pumpTest.NewRandomBolus(), + "bolus-2": pumpTest.NewRandomBolus(), + } + var settingsBolusDatum bson.M + + BeforeEach(func() { + settingsBolusDatum = getBSONData(pumpSettingsDatum) + settingsBolusDatum["bolus"] = bolusData + settingsBolusDatum["_id"] = expectedID + }) + + It("should do nothing when has no bolus", func() { + settingsBolusDatum["bolus"] = nil + Expect(settingsBolusDatum["bolus"]).To(BeNil()) + err := utils.ApplyBaseChanges(settingsBolusDatum) + Expect(err).To(BeNil()) + Expect(settingsBolusDatum["bolus"]).To(BeNil()) + }) + + It("should rename as boluses when bolus found", func() { + settingsBolusDatum["bolus"] = nil + Expect(settingsBolusDatum["bolus"]).To(BeNil()) + err := utils.ApplyBaseChanges(settingsBolusDatum) + Expect(err).To(BeNil()) + Expect(settingsBolusDatum["bolus"]).To(BeNil()) + }) + }) + }) + Context("datum with glucose", func() { + var newContinuous = func(units *string) *continuous.Continuous { + datum := continuous.New() + datum.Glucose = *glucoseTest.NewGlucose(units) + datum.Type = "cbg" + *datum.ID = expectedID + *datum.UserID = "some-user-id" + *datum.DeviceID = "some-device-id" + theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") + *datum.Time = theTime + return datum + } + + It("should do nothing when value is already correct", func() { + mmoll := glucose.MmolL + cbg := newContinuous(&mmoll) + cbgData := getBSONData(cbg) + cbgData["_id"] = expectedID + cbgData["value"] = 4.88466 + + Expect(cbgData["value"]).To(Equal(4.88466)) + err := utils.ApplyBaseChanges(cbgData) + Expect(err).To(BeNil()) + Expect(cbgData["value"]).To(Equal(4.88466)) + }) + It("should update the value when the precesion is too accurate correct", func() { + mmoll := glucose.MmolL + cbg := newContinuous(&mmoll) + cbgData := getBSONData(cbg) + cbgData["_id"] = expectedID + cbgData["value"] = 4.88465823212007 + + Expect(cbgData["value"]).To(Equal(4.88465823212007)) + err := utils.ApplyBaseChanges(cbgData) + Expect(err).To(BeNil()) + Expect(cbgData["value"]).To(Equal(4.88466)) + }) + }) + }) + var _ = Describe("GetDatumUpdates", func() { var existingBolusDatum bson.M const expectedID = "some-id" From bef257e266dbce508c01052fc5f4d4c3b15746ec Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 7 Feb 2024 23:28:45 +1300 Subject: [PATCH 182/413] payload test --- .../device/override/settings/pump/pump.go | 4 -- .../override/settings/pump/pump_test.go | 11 ---- .../utils/utils_test.go | 57 ++++++++++++------- 3 files changed, 38 insertions(+), 34 deletions(-) diff --git a/data/types/device/override/settings/pump/pump.go b/data/types/device/override/settings/pump/pump.go index 7b9d42063c..11c3949045 100644 --- a/data/types/device/override/settings/pump/pump.go +++ b/data/types/device/override/settings/pump/pump.go @@ -131,10 +131,6 @@ func (p *Pump) Validate(validator structure.Validator) { } else if p.BloodGlucoseTarget != nil { unitsValidator.ReportError(structureValidator.ErrorValueNotExists()) } - - // if p.BloodGlucoseTarget == nil && p.BasalRateScaleFactor == nil && p.CarbohydrateRatioScaleFactor == nil && p.InsulinSensitivityScaleFactor == nil { - // validator.ReportError(structureValidator.ErrorValuesNotExistForAny("bgTarget", "basalRateScaleFactor", "carbRatioScaleFactor", "insulinSensitivityScaleFactor")) - // } } func (p *Pump) Normalize(normalizer data.Normalizer) { diff --git a/data/types/device/override/settings/pump/pump_test.go b/data/types/device/override/settings/pump/pump_test.go index e94e2d5e69..d867f54552 100644 --- a/data/types/device/override/settings/pump/pump_test.go +++ b/data/types/device/override/settings/pump/pump_test.go @@ -679,17 +679,6 @@ var _ = Describe("Pump", func() { datum.BloodGlucoseTarget = dataBloodGlucoseTest.RandomTarget(unitsBloodGlucose) }, ), - // Entry("one of required missing", - // pointer.FromString("mmol/L"), - // func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { - // datum.BloodGlucoseTarget = nil - // datum.BasalRateScaleFactor = nil - // datum.CarbohydrateRatioScaleFactor = nil - // datum.InsulinSensitivityScaleFactor = nil - // datum.Units = nil - // }, - // errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValuesNotExistForAny("bgTarget", "basalRateScaleFactor", "carbRatioScaleFactor", "insulinSensitivityScaleFactor"), "", NewMeta()), - // ), Entry("multiple errors", pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 3e057eafc5..cd28089b12 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -7,6 +7,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" "github.com/tidepool-org/platform/data/blood/glucose" "github.com/tidepool-org/platform/data/normalizer" @@ -16,6 +17,8 @@ import ( "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/data/types/settings/pump" pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" + "github.com/tidepool-org/platform/metadata" + metadataTest "github.com/tidepool-org/platform/metadata/test" "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils/test" "github.com/tidepool-org/platform/pointer" @@ -34,27 +37,19 @@ var _ = Describe("back-37", func() { return bsonData } - Context("pumpSettings", func() { + var pumpSettingsDatum *pump.Pump - var pumpSettingsDatum *pump.Pump - var settingsBolusDatum bson.M + BeforeEach(func() { + mmolL := pump.DisplayBloodGlucoseUnitsMmolPerL + pumpSettingsDatum = pumpTest.NewPump(&mmolL) + *pumpSettingsDatum.ID = expectedID + *pumpSettingsDatum.UserID = "some-user-id" + *pumpSettingsDatum.DeviceID = "some-device-id" + theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") + *pumpSettingsDatum.Time = theTime + }) - BeforeEach(func() { - mmolL := pump.DisplayBloodGlucoseUnitsMmolPerL - pumpSettingsDatum = pumpTest.NewPump(&mmolL) - *pumpSettingsDatum.ID = expectedID - *pumpSettingsDatum.UserID = "some-user-id" - *pumpSettingsDatum.DeviceID = "some-device-id" - theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") - *pumpSettingsDatum.Time = theTime - var bolusData = &pump.BolusMap{ - "bolus-1": pumpTest.NewRandomBolus(), - "bolus-2": pumpTest.NewRandomBolus(), - } - settingsBolusDatum = getBSONData(pumpSettingsDatum) - settingsBolusDatum["bolus"] = bolusData - settingsBolusDatum["_id"] = expectedID - }) + Context("pumpSettings", func() { Context("with mis-named jellyfish bolus", func() { var bolusData = &pump.BolusMap{ @@ -64,6 +59,7 @@ var _ = Describe("back-37", func() { var settingsBolusDatum bson.M BeforeEach(func() { + settingsBolusDatum = getBSONData(pumpSettingsDatum) settingsBolusDatum["bolus"] = bolusData settingsBolusDatum["_id"] = expectedID @@ -124,6 +120,29 @@ var _ = Describe("back-37", func() { Expect(cbgData["value"]).To(Equal(4.88466)) }) }) + Context("datum with string payload", func() { + var datumWithPayload primitive.M + var payload *metadata.Metadata + BeforeEach(func() { + datumWithPayload = getBSONData(pumpSettingsDatum) + payload = metadataTest.RandomMetadata() + datumWithPayload["payload"] = payload + }) + + It("should do nothing when value is already correct", func() { + Expect(datumWithPayload["payload"]).To(Equal(payload)) + err := utils.ApplyBaseChanges(datumWithPayload) + Expect(err).To(BeNil()) + Expect(datumWithPayload["payload"]).To(Equal(payload)) + }) + // It("should update the payload when it is a string", func() { + // datumWithPayload["payload"] = fmt.Sprintf("%v", *payload) + // Expect(datumWithPayload["payload"]).To(Equal(fmt.Sprintf("%v", *payload))) + // err := utils.ApplyBaseChanges(datumWithPayload) + // Expect(err).To(BeNil()) + // Expect(datumWithPayload["payload"]).To(Equal(payload)) + // }) + }) }) var _ = Describe("GetDatumUpdates", func() { From 8dcb33a6903fb7eda49e93db96deee166b74b229 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 8 Feb 2024 08:51:18 +1300 Subject: [PATCH 183/413] test for payload and annotations --- .../utils/utils.go | 64 ------------------- .../utils/utils_test.go | 48 +++++++++++--- 2 files changed, 38 insertions(+), 74 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 3a70279a57..f395163536 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -163,66 +163,6 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { return nil, err } - // switch dType { - // case pump.Type: - // if boluses := bsonData["bolus"]; boluses != nil { - // bsonData["boluses"] = boluses - // //TODO delete from mongo - // delete(bsonData, "bolus") - // } - // //TODO Entry("returns converted value for mmol/L units with incorrect precision", pointer.FromFloat64(4.88465823212007), pointer.FromString("mmol/L"), pointer.FromFloat64(4.88466)), - // // case selfmonitored.Type, ketone.Type, continuous.Type: - // // units := fmt.Sprintf("%v", bsonData["units"]) - // // if units == glucose.MmolL || units == glucose.Mmoll { - // // floatStr := fmt.Sprintf("%v", bsonData["value"]) - // // floatParts := strings.Split(floatStr, ".") - // // if len(floatParts) == 2 { - // // if len(floatParts[1]) > 5 { - // // //TODO update in mongo - // // if floatVal, ok := bsonData["value"].(float64); ok { - // // mgdlVal := floatVal * glucose.MmolLToMgdLConversionFactor - // // intValue := int(mgdlVal/glucose.MmolLToMgdLConversionFactor*glucose.MmolLToMgdLPrecisionFactor + 0.5) - // // floatValue := float64(intValue) / glucose.MmolLToMgdLPrecisionFactor - // // bsonData["value"] = floatValue - // // } - // // } - // // } - // // } - // case basal.Type: - // if percent := bsonData["percent"]; percent != nil { - // //TODO delete from mongo - // delete(bsonData, "percent") - // } - // } - - // if payload := bsonData["payload"]; payload != nil { - // if _, ok := payload.(string); ok { - // dataBytes, err := bson.Marshal(payload) - // if err != nil { - // return nil, err - // } - // var payloadMetadata metadata.Metadata - // err = bson.Unmarshal(dataBytes, &payloadMetadata) - // if err != nil { - // return nil, errorsP.Newf("payload could not be set from %v ", string(dataBytes)) - // } - // bsonData["payload"] = &payloadMetadata - // } - // } - // if annotations := bsonData["annotations"]; annotations != nil { - // if _, ok := annotations.(string); ok { - // dataBytes, err := bson.Marshal(annotations) - // if err != nil { - // return nil, err - // } - // var metadataArray metadata.MetadataArray - // if err := bson.Unmarshal(dataBytes, &metadataArray); err != nil { - // return nil, errorsP.Newf("annotations could not be set from %v ", string(dataBytes)) - // } - // bsonData["annotations"] = &metadataArray - // } - // } - incomingJSONData, err := json.Marshal(bsonData) if err != nil { return nil, err @@ -241,10 +181,6 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { if datum != nil && *datum != nil { (*datum).Validate(validator) (*datum).Normalize(normalizer) - - // if (*datum).GetType() == selfmonitored.Type { - // //TODO - // } } else { return nil, errorsP.Newf("no datum returned for id=[%s]", dID) } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index cd28089b12..43765aaf71 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -1,6 +1,7 @@ package utils_test import ( + "fmt" "strings" "time" @@ -16,7 +17,9 @@ import ( bolusTest "github.com/tidepool-org/platform/data/types/bolus/test" "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/data/types/settings/pump" + pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" + "github.com/tidepool-org/platform/metadata" metadataTest "github.com/tidepool-org/platform/metadata/test" "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" @@ -126,22 +129,47 @@ var _ = Describe("back-37", func() { BeforeEach(func() { datumWithPayload = getBSONData(pumpSettingsDatum) payload = metadataTest.RandomMetadata() - datumWithPayload["payload"] = payload + datumWithPayload["payload"] = *payload }) It("should do nothing when value is already correct", func() { - Expect(datumWithPayload["payload"]).To(Equal(payload)) + Expect(datumWithPayload["payload"]).To(Equal(*payload)) err := utils.ApplyBaseChanges(datumWithPayload) Expect(err).To(BeNil()) - Expect(datumWithPayload["payload"]).To(Equal(payload)) + Expect(datumWithPayload["payload"]).To(Equal(*payload)) + }) + It("should update the payload when it is a string", func() { + Skip("sort out setting as string") + datumWithPayload["payload"] = fmt.Sprintf("%v", getBSONData(*payload)) + Expect(datumWithPayload["payload"]).To(Equal(fmt.Sprintf("%v", *payload))) + err := utils.ApplyBaseChanges(datumWithPayload) + Expect(err).To(BeNil()) + Expect(datumWithPayload["payload"]).To(Equal(*payload)) + }) + }) + Context("datum with string annotations", func() { + var datumWithAnnotation primitive.M + var annotations *metadata.MetadataArray + BeforeEach(func() { + datumWithAnnotation = getBSONData(pumpSettingsDatum) + annotations = metadataTest.RandomMetadataArray() + datumWithAnnotation["annotations"] = *annotations + }) + + It("should do nothing when value is already correct", func() { + Expect(datumWithAnnotation["annotations"]).To(Equal(*annotations)) + err := utils.ApplyBaseChanges(datumWithAnnotation) + Expect(err).To(BeNil()) + Expect(datumWithAnnotation["annotations"]).To(Equal(*annotations)) + }) + It("should update the annotations when it is a string", func() { + Skip("sort out setting as string") + datumWithAnnotation["annotations"] = fmt.Sprintf("%v", getBSONData(*annotations)) + Expect(datumWithAnnotation["annotations"]).To(Equal(fmt.Sprintf("%v", *annotations))) + err := utils.ApplyBaseChanges(datumWithAnnotation) + Expect(err).To(BeNil()) + Expect(datumWithAnnotation["annotations"]).To(Equal(*annotations)) }) - // It("should update the payload when it is a string", func() { - // datumWithPayload["payload"] = fmt.Sprintf("%v", *payload) - // Expect(datumWithPayload["payload"]).To(Equal(fmt.Sprintf("%v", *payload))) - // err := utils.ApplyBaseChanges(datumWithPayload) - // Expect(err).To(BeNil()) - // Expect(datumWithPayload["payload"]).To(Equal(payload)) - // }) }) }) From 1b52af2777c0288a69d7bf61aa833ee4bf58c90d Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 8 Feb 2024 09:37:19 +1300 Subject: [PATCH 184/413] remove calc wizard from audit --- .../utils/example.json | 1032 +++++++++++++++++ .../utils/utils.go | 6 + 2 files changed, 1038 insertions(+) create mode 100644 migrations/20231128_jellyfish_migration/utils/example.json diff --git a/migrations/20231128_jellyfish_migration/utils/example.json b/migrations/20231128_jellyfish_migration/utils/example.json new file mode 100644 index 0000000000..8213c0cb82 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/utils/example.json @@ -0,0 +1,1032 @@ +[ + { + "_id": "00000rnk44mf6pha8rmjb8mpiuipkdaa", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 4.88465823212007, + "to": 4.88466 + } + ] + }, + { + "_id": "00001jb82bd12eg0eca8k2c49ujfnk8l", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 8.104092066926478, + "to": 8.10409 + } + ] + }, + { + "_id": "00003sa2flpghjst5u4jnrt9kbt4dvlr", + "diff": [ + { + "type": "delete", + "path": ["payload", "temp_rate"], + "from": null, + "to": null + }, + { + "type": "delete", + "path": ["payload", "algorithm_rate"], + "from": null, + "to": null + } + ] + }, + { + "_id": "00009es5b8a4b4ee3v06f53df255hmpv", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 7.882062147284658, + "to": 7.88206 + } + ] + }, + { + "_id": "0000a6upv4rpd6n0am7t1uvlbe9snn4a", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 12.211645580300173, + "to": 12.21165 + } + ] + }, + { + "_id": "0000kr4f38gv49kep801vlj08cbmcfi1", + "diff": [ + { + "type": "delete", + "path": ["payload", "temp_rate"], + "from": null, + "to": null + } + ] + }, + { + "_id": "0000o3ocekq00achukuojpst03u3c9t4", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 8.270614506657845, + "to": 8.27061 + } + ] + }, + { + "_id": "0000orq7oc766e2i5tsps36ifpgq49vr", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 6.438867669612819, + "to": 6.43887 + } + ] + }, + { + "_id": "0000s092sqmi3uq1psma1s9tnojog436", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 9.87641966364939, + "to": 9.87642 + } + ] + }, + { + "_id": "0000ugjo3nbjdm43l67ckm1vksu7ha8i", + "diff": [ + { + "type": "delete", + "path": ["payload", "temp_rate"], + "from": null, + "to": null + } + ] + }, + { + "_id": "0000ushg75s767rrbuj34r9lgeppfm5m", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 7.382494828090559, + "to": 7.38249 + } + ] + }, + { + "_id": "0001394npef2cp1n2du0j0aon6m35va9", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 8.548151906210121, + "to": 8.54815 + } + ] + }, + { + "_id": "000141vp4hq535kmn55kj484chh1526f", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 11.157003462001523, + "to": 11.157 + } + ] + }, + { + "_id": "00018qlmsrs5vvs2ossvujrkgoq63ui6", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 6.050315310239632, + "to": 6.05032 + } + ] + }, + { + "_id": "0001gfdvg0sorbqcqmsvaeqatul4gr4r", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 8.659166866031033, + "to": 8.65917 + } + ] + }, + { + "_id": "0001k7kdh3quebrt74fht9q2estmq75i", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 8.992211745493764, + "to": 8.99221 + } + ] + }, + { + "_id": "0001nrq5d8r9thkk1badhc7sqv0b28dk", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 8.104092066926478, + "to": 8.10409 + } + ] + }, + { + "_id": "0001qgq51nngk6ubjel2c544frhch0eq", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 12.211645580300173, + "to": 12.21165 + } + ] + }, + { + "_id": "0001v81kcacfc9qhpvjmhr1ealooee2f", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 9.991346383881961, + "to": 9.99135 + } + ] + }, + { + "_id": "0001vqvo2jci3thogtb1ldbanc7t3euh", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 7.271479868269648, + "to": 7.27148 + } + ] + }, + { + "_id": "00020drvhoek75e31s2eb2ihr3hneab0", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 10.268883783434237, + "to": 10.26888 + } + ] + }, + { + "_id": "00021gjfc88sh2853sa9kvo8mibk3btb", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 6.1058227901500866, + "to": 6.10582 + } + ] + }, + { + "_id": "00022iu9mqq7vl22qg8cf27pl23mei6m", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 6.66089758925464, + "to": 6.6609 + } + ] + }, + { + "_id": "000272sak7skr78u235jvobkg2j2l7db", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 6.66089758925464, + "to": 6.6609 + } + ] + }, + { + "_id": "0002hhgscc8stmmgl56q2t5l4voag0k2", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 8.21510702674739, + "to": 8.21511 + } + ] + }, + { + "_id": "0002mvusipdajgceeghbmpcqo4ln3j2e", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 10.157868823613326, + "to": 10.15787 + } + ] + }, + { + "_id": "0002pqfv2solvi4lpuslibloq8n70egk", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 6.161330270060542, + "to": 6.16133 + } + ] + }, + { + "_id": "0002qi2gkb52qtljm471fqqfm360ir4k", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 11.601063301285166, + "to": 11.60106 + } + ] + }, + { + "_id": "0002sn9beaeh9j81v3djcbmapuftu23n", + "diff": [ + { + "type": "delete", + "path": ["payload", "temp_rate"], + "from": null, + "to": null + } + ] + }, + { + "_id": "0002tt08v467lkusp8dti02a1of7nq9f", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 7.549017267821926, + "to": 7.54902 + } + ] + }, + { + "_id": "0002umkmpa7atejb43k56ut0soqdq9jn", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 6.882927508896461, + "to": 6.88293 + } + ] + }, + { + "_id": "0002uu965smbnbp8uu95a21dmh270g67", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 6.938434988806917, + "to": 6.93843 + } + ] + }, + { + "_id": "0002vd9ik54eh1qrs4rinp3o6frt53pn", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 13.432810138330192, + "to": 13.43281 + } + ] + }, + { + "_id": "00030vvt9bf2fh3akggqko8e9hbk1gmp", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 8.548151906210121, + "to": 8.54815 + } + ] + }, + { + "_id": "00032090p27jjo7en5v81bc86sk500eg", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 5.7727779106873545, + "to": 5.77278 + } + ] + }, + { + "_id": "00032ph132hqdl11ljcosfs118opd6uj", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 4.16306099328415, + "to": 4.16306 + } + ] + }, + { + "_id": "000359urjliju7o3vhemciluk0b8go5h", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 6.272345229881453, + "to": 6.27235 + } + ] + }, + { + "_id": "00035k3g10h5s065fm7ujdkqsffdpefj", + "diff": [ + { + "type": "delete", + "path": ["payload", "temp_rate"], + "from": null, + "to": null + } + ] + }, + { + "_id": "00035qapsmj0g0tj5911j88861e1ja85", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 7.826554667374202, + "to": 7.82655 + } + ] + }, + { + "_id": "0003c7lqj9o23tk7mrf3ous8bqit32qn", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 8.21510702674739, + "to": 8.21511 + } + ] + }, + { + "_id": "0003eh53gp42t49i3p50rtn5t8nhrce5", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 4.829150752209614, + "to": 4.82915 + } + ] + }, + { + "_id": "0003f9b07hcfpfvl7o9mn49kg4sp89jg", + "diff": [ + { + "type": "delete", + "path": ["payload", "temp_rate"], + "from": null, + "to": null + } + ] + }, + { + "_id": "0003hf5lemo91skk3s64nvjqiolci7ca", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 8.437136946389211, + "to": 8.43714 + } + ] + }, + { + "_id": "0003i37c2j7llmbtkkja8td6p3cl72fm", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 12.211645580300173, + "to": 12.21165 + } + ] + }, + { + "_id": "0003jngv0eod115brtuua83d2kpu336a", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 10.990481022270156, + "to": 10.99048 + } + ] + }, + { + "_id": "0003k66j2k63js2kcamv5flmcftjv0vi", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 5.162195631672346, + "to": 5.1622 + } + ] + }, + { + "_id": "0003q61k26agdd8pputarp9tngnnl4bm", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 4.88465823212007, + "to": 4.88466 + } + ] + }, + { + "_id": "0003r9mmr8nbtkqn53b3ssucj6dnon3s", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 4.440598392836427, + "to": 4.4406 + } + ] + }, + { + "_id": "0003rgeeqhrgaljcvr0vn978mhh0urcr", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 5.550747991045533, + "to": 5.55075 + } + ] + }, + { + "_id": "0003sc9q9d2cgjblnbjpor1n5be4gdgq", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 6.383360189702364, + "to": 6.38336 + } + ] + }, + { + "_id": "0004b6tsha75kvbltqn36eqknhgpokj7", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 2.2202991964182135, + "to": 2.2203 + } + ] + }, + { + "_id": "0004etdb73eniso7uesle4ebv3unbmhk", + "diff": [ + { + "type": "delete", + "path": ["payload", "algorithm_rate"], + "from": null, + "to": null + }, + { + "type": "delete", + "path": ["payload", "temp_rate"], + "from": null, + "to": null + } + ] + }, + { + "_id": "0004h0iv775p64gu5p9bsgupfeng7rft", + "diff": [ + { + "type": "delete", + "path": ["payload", "temp_rate"], + "from": null, + "to": null + } + ] + }, + { + "_id": "0004hlsdjp3sm3ri89qma8nv6qcp5q3f", + "diff": [ + { + "type": "delete", + "path": ["payload", "temp_rate"], + "from": null, + "to": null + } + ] + }, + { + "_id": "0004jt901qccjhlukths98e2g6e3kn28", + "diff": [ + { + "type": "delete", + "path": ["payload", "temp_rate"], + "from": null, + "to": null + } + ] + }, + { + "_id": "0004rreii78v6da848mniincnb55qjkv", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 14.26542233698702, + "to": 14.26542 + } + ] + }, + { + "_id": "000556rqprsdce1g00gf3248ibduqns6", + "diff": [ + { + "type": "delete", + "path": ["payload", "temp_rate"], + "from": null, + "to": null + } + ] + }, + { + "_id": "00055b6nf17dpga93vi8d9npgja8oui2", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 7.049449948627828, + "to": 7.04945 + } + ] + }, + { + "_id": "000570t2klm76u0pge2fa1l6sb2vacou", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 4.829150752209614, + "to": 4.82915 + } + ] + }, + { + "_id": "0005jqjjc16r97d1j4kjsul8gv5s4m85", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 15.153542015554306, + "to": 15.15354 + } + ] + }, + { + "_id": "0005s07sgj51fi9tg30cdmbejdrtktva", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 10.82395858253879, + "to": 10.82396 + } + ] + }, + { + "_id": "0005uf2eav6074jqr9kfais0gdnufhv6", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 12.211645580300173, + "to": 12.21165 + } + ] + }, + { + "_id": "00065i6mgho4lk4ljel4iad1sh12ks6a", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 8.104092066926478, + "to": 8.10409 + } + ] + }, + { + "_id": "000662f21o6q6h563se5dh1bpuji1j8s", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 2.164791716507758, + "to": 2.16479 + } + ] + }, + { + "_id": "0006aji37fd7sn1abvdh14g5bu04cqa6", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 10.879466062449245, + "to": 10.87947 + } + ] + }, + { + "_id": "0006asj48h8inkrq03mudant3sqbm2j7", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 6.383360189702364, + "to": 6.38336 + } + ] + }, + { + "_id": "0006au8dsvu6590iv9oj828rd5p1u37e", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 8.104092066926478, + "to": 8.10409 + } + ] + }, + { + "_id": "0006iepb218jd1f51upa4o6fia8sklfp", + "diff": [ + { + "type": "delete", + "path": ["payload", "temp_rate"], + "from": null, + "to": null + } + ] + }, + { + "_id": "0006ighrh1qkbfmmqmg9s81vvvs9c8pd", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 7.382494828090559, + "to": 7.38249 + } + ] + }, + { + "_id": "0006j5vr2m5r55jcu5lt9looau2s71fm", + "diff": [ + { + "type": "delete", + "path": ["payload", "temp_rate"], + "from": null, + "to": null + } + ] + }, + { + "_id": "00000rnk44mf6pha8rmjb8mpiuipkdaa", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 4.88465823212007, + "to": 4.88466 + } + ] + }, + { + "_id": "00001jb82bd12eg0eca8k2c49ujfnk8l", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 8.104092066926478, + "to": 8.10409 + } + ] + }, + { + "_id": "00003sa2flpghjst5u4jnrt9kbt4dvlr", + "diff": [ + { + "type": "delete", + "path": ["payload", "temp_rate"], + "from": null, + "to": null + }, + { + "type": "delete", + "path": ["payload", "algorithm_rate"], + "from": null, + "to": null + } + ] + }, + { + "_id": "00009es5b8a4b4ee3v06f53df255hmpv", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 7.882062147284658, + "to": 7.88206 + } + ] + }, + { + "_id": "0000a6upv4rpd6n0am7t1uvlbe9snn4a", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 12.211645580300173, + "to": 12.21165 + } + ] + }, + { + "_id": "0000kr4f38gv49kep801vlj08cbmcfi1", + "diff": [ + { + "type": "delete", + "path": ["payload", "temp_rate"], + "from": null, + "to": null + } + ] + }, + { + "_id": "0000o3ocekq00achukuojpst03u3c9t4", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 8.270614506657845, + "to": 8.27061 + } + ] + }, + { + "_id": "0000orq7oc766e2i5tsps36ifpgq49vr", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 6.438867669612819, + "to": 6.43887 + } + ] + }, + { + "_id": "0000s092sqmi3uq1psma1s9tnojog436", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 9.87641966364939, + "to": 9.87642 + } + ] + }, + { + "_id": "0000ugjo3nbjdm43l67ckm1vksu7ha8i", + "diff": [ + { + "type": "delete", + "path": ["payload", "temp_rate"], + "from": null, + "to": null + } + ] + }, + { + "_id": "0000ushg75s767rrbuj34r9lgeppfm5m", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 7.382494828090559, + "to": 7.38249 + } + ] + }, + { + "_id": "0001394npef2cp1n2du0j0aon6m35va9", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 8.548151906210121, + "to": 8.54815 + } + ] + }, + { + "_id": "000141vp4hq535kmn55kj484chh1526f", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 11.157003462001523, + "to": 11.157 + } + ] + }, + { + "_id": "00018qlmsrs5vvs2ossvujrkgoq63ui6", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 6.050315310239632, + "to": 6.05032 + } + ] + }, + { + "_id": "0001gfdvg0sorbqcqmsvaeqatul4gr4r", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 8.659166866031033, + "to": 8.65917 + } + ] + }, + { + "_id": "0001k7kdh3quebrt74fht9q2estmq75i", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 8.992211745493764, + "to": 8.99221 + } + ] + }, + { + "_id": "0001nrq5d8r9thkk1badhc7sqv0b28dk", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 8.104092066926478, + "to": 8.10409 + } + ] + }, + { + "_id": "0001qgq51nngk6ubjel2c544frhch0eq", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 12.211645580300173, + "to": 12.21165 + } + ] + }, + { + "_id": "0001v81kcacfc9qhpvjmhr1ealooee2f", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 9.991346383881961, + "to": 9.99135 + } + ] + }, + { + "_id": "0001vqvo2jci3thogtb1ldbanc7t3euh", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 7.271479868269648, + "to": 7.27148 + } + ] + }, + { + "_id": "00020drvhoek75e31s2eb2ihr3hneab0", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 10.268883783434237, + "to": 10.26888 + } + ] + }, + { + "_id": "00021gjfc88sh2853sa9kvo8mibk3btb", + "diff": [ + { + "type": "update", + "path": ["value"], + "from": 6.1058227901500866, + "to": 6.10582 + } + ] + } +] diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index f395163536..1fe04c9918 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -18,6 +18,7 @@ import ( "github.com/tidepool-org/platform/data/deduplicator/deduplicator" "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/data/types/basal" + "github.com/tidepool-org/platform/data/types/calculator" "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" @@ -123,6 +124,11 @@ func ApplyBaseChanges(bsonData bson.M) error { //TODO delete from mongo delete(bsonData, "percent") } + case calculator.Type: + if bolus := bsonData["bolus"]; bolus != nil { + //TODO ignore these ?? + delete(bsonData, "bolus") + } } if payload := bsonData["payload"]; payload != nil { From 649bcf54b3e04341334118e29ee869ed1fdad7b7 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 12 Feb 2024 12:25:13 +1300 Subject: [PATCH 185/413] build mongo query form difference --- .../utils/utils.go | 112 +++++++++++++----- .../utils/utils_test.go | 56 +++++++-- 2 files changed, 133 insertions(+), 35 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 1fe04c9918..3e116edc87 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -9,9 +9,9 @@ import ( "strings" "time" - "github.com/r3labs/diff/v3" "go.mongodb.org/mongo-driver/bson" + "github.com/r3labs/diff/v3" "github.com/tidepool-org/platform/data" "github.com/tidepool-org/platform/data/blood/glucose" @@ -161,25 +161,8 @@ func ApplyBaseChanges(bsonData bson.M) error { return nil } -func ProcessDatum(bsonData bson.M) (data.Datum, error) { - - dID := fmt.Sprintf("%v", bsonData["_id"]) - - if err := ApplyBaseChanges(bsonData); err != nil { - return nil, err - } - - incomingJSONData, err := json.Marshal(bsonData) - if err != nil { - return nil, err - } - ojbData := map[string]interface{}{} - if err := json.Unmarshal(incomingJSONData, &ojbData); err != nil { - return nil, err - } - - //parsing - parser := structureParser.NewObject(&ojbData) +func BuildDatum(id string, objectData map[string]interface{}) (*data.Datum, error) { + parser := structureParser.NewObject(&objectData) validator := structureValidator.New() normalizer := dataNormalizer.New() @@ -188,7 +171,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { (*datum).Validate(validator) (*datum).Normalize(normalizer) } else { - return nil, errorsP.Newf("no datum returned for id=[%s]", dID) + return nil, errorsP.Newf("no datum returned for id=[%s]", id) } validator.Bool("_active", parser.Bool("_active")).Exists() @@ -219,25 +202,98 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { if err := normalizer.Error(); err != nil { return nil, err } + return datum, nil +} +func GetDifference(id string, datum interface{}, rawObject map[string]interface{}) ([]bson.M, error) { + difference := []bson.M{} outgoingJSONData, err := json.Marshal(datum) if err != nil { return nil, err } - processedData := map[string]interface{}{} - if err := json.Unmarshal(outgoingJSONData, &processedData); err != nil { + processedObject := map[string]interface{}{} + if err := json.Unmarshal(outgoingJSONData, &processedObject); err != nil { return nil, err } // these are extras that we want to leave on the original object - notRequired := []string{"_active", "_groupId", "_id", "_userId", "_version", "_schemaVersion", "_deduplicator", "uploadId", "createdTime", "guid", "modifiedTime", "_archivedTime"} - for _, key := range notRequired { - delete(ojbData, key) + // notRequired := []string{"_active", "_groupId", "_id", "_userId", "_version", "_schemaVersion", "_deduplicator", "uploadId", "createdTime", "guid", "modifiedTime", "_archivedTime"} + // for _, key := range notRequired { + // delete(rawObject, key) + // } + + changelog, err := diff.Diff(rawObject, processedObject, diff.StructMapKeySupport()) + if err != nil { + return nil, err + } + logDiff(id, changelog) + + set := bson.M{} + unset := bson.M{} + rename := bson.M{} + + // ["path","to","change"] + // {path: {to: {change: true}}} + var getValue = func(path []string, val interface{}) interface{} { + if len(path) == 1 { + return val + } else if len(path) == 2 { + return bson.M{path[1]: val} + } + return bson.M{path[1]: bson.M{path[2]: val}} + } + + for _, change := range changelog { + switch change.Type { + case diff.CREATE: + set[change.Path[0]] = getValue(change.Path, change.To) + case diff.DELETE: + unset[change.Path[0]] = getValue(change.Path, "") + case diff.UPDATE: + rename[change.Path[0]] = getValue(change.Path, change.To) + } } - changelog, _ := diff.Diff(ojbData, processedData, diff.StructMapKeySupport()) - logDiff(dID, changelog) + if len(set) > 0 { + difference = append(difference, bson.M{"$set": set}) + } + if len(rename) > 0 { + difference = append(difference, bson.M{"$rename": rename}) + } + if len(unset) > 0 { + difference = append(difference, bson.M{"$unset": unset}) + } + return difference, nil +} + +func ProcessDatum(bsonData bson.M) (data.Datum, error) { + + dID := fmt.Sprintf("%v", bsonData["_id"]) + + if err := ApplyBaseChanges(bsonData); err != nil { + return nil, err + } + + incomingJSONData, err := json.Marshal(bsonData) + if err != nil { + return nil, err + } + ojbData := map[string]interface{}{} + if err := json.Unmarshal(incomingJSONData, &ojbData); err != nil { + return nil, err + } + + datum, err := BuildDatum(dID, ojbData) + if err != nil { + return nil, err + } + + difference, err := GetDifference(dID, datum, ojbData) + if err != nil { + return nil, err + } + log.Printf("diff: %v", difference) return *datum, nil } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 43765aaf71..cd2f4730aa 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -1,6 +1,7 @@ package utils_test import ( + "encoding/json" "fmt" "strings" "time" @@ -29,17 +30,17 @@ import ( var _ = Describe("back-37", func() { var _ = Describe("utils", func() { + var getBSONData = func(datum interface{}) bson.M { + var bsonData bson.M + bsonAsByte, _ := bson.Marshal(&datum) + bson.Unmarshal(bsonAsByte, &bsonData) + return bsonData + } + var _ = Describe("ApplyBaseChanges", func() { const expectedID = "some-id" - var getBSONData = func(datum interface{}) bson.M { - var bsonData bson.M - bsonAsByte, _ := bson.Marshal(&datum) - bson.Unmarshal(bsonAsByte, &bsonData) - return bsonData - } - var pumpSettingsDatum *pump.Pump BeforeEach(func() { @@ -173,6 +174,47 @@ var _ = Describe("back-37", func() { }) }) + var _ = Describe("GetDifference", func() { + + const expectedID = "difference-id" + + var getRawData = func(datum interface{}) map[string]interface{} { + var rawObject map[string]interface{} + asByte, _ := json.Marshal(&datum) + json.Unmarshal(asByte, &rawObject) + return rawObject + } + + //var pumpSettingsDatum *pump.Pump + var incomingObject map[string]interface{} + var datumObject bson.M + + BeforeEach(func() { + datumObject = getBSONData(test.AutomatedBasalTandem) + incomingObject = getRawData(test.AutomatedBasalTandem) + + }) + + It("has no difference", func() { + diff, err := utils.GetDifference(expectedID, datumObject, incomingObject) + Expect(err).To(BeNil()) + Expect(diff).ToNot(BeNil()) + Expect(diff).To(Equal([]bson.M{})) + }) + It("set for missing properties", func() { + delete(incomingObject, "deliveryType") + diff, err := utils.GetDifference(expectedID, datumObject, incomingObject) + Expect(err).To(BeNil()) + Expect(diff).To(Equal([]bson.M{{"$set": bson.M{"deliveryType": "automated"}}})) + }) + It("unset for unwanted properties", func() { + incomingObject["random"] = map[string]interface{}{"extra": true} + diff, err := utils.GetDifference(expectedID, datumObject, incomingObject) + Expect(err).To(BeNil()) + Expect(diff).To(Equal([]bson.M{{"$unset": bson.M{"random": ""}}})) + }) + }) + var _ = Describe("GetDatumUpdates", func() { var existingBolusDatum bson.M const expectedID = "some-id" From c70e95d62db4b13ecb8060ac6c838a1da38c9f1b Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 12 Feb 2024 13:42:15 +1300 Subject: [PATCH 186/413] don't build diff on internal properties --- .../utils/example.json | 1032 ----------------- .../utils/utils.go | 39 +- .../utils/utils_test.go | 8 +- 3 files changed, 33 insertions(+), 1046 deletions(-) delete mode 100644 migrations/20231128_jellyfish_migration/utils/example.json diff --git a/migrations/20231128_jellyfish_migration/utils/example.json b/migrations/20231128_jellyfish_migration/utils/example.json deleted file mode 100644 index 8213c0cb82..0000000000 --- a/migrations/20231128_jellyfish_migration/utils/example.json +++ /dev/null @@ -1,1032 +0,0 @@ -[ - { - "_id": "00000rnk44mf6pha8rmjb8mpiuipkdaa", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 4.88465823212007, - "to": 4.88466 - } - ] - }, - { - "_id": "00001jb82bd12eg0eca8k2c49ujfnk8l", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 8.104092066926478, - "to": 8.10409 - } - ] - }, - { - "_id": "00003sa2flpghjst5u4jnrt9kbt4dvlr", - "diff": [ - { - "type": "delete", - "path": ["payload", "temp_rate"], - "from": null, - "to": null - }, - { - "type": "delete", - "path": ["payload", "algorithm_rate"], - "from": null, - "to": null - } - ] - }, - { - "_id": "00009es5b8a4b4ee3v06f53df255hmpv", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 7.882062147284658, - "to": 7.88206 - } - ] - }, - { - "_id": "0000a6upv4rpd6n0am7t1uvlbe9snn4a", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 12.211645580300173, - "to": 12.21165 - } - ] - }, - { - "_id": "0000kr4f38gv49kep801vlj08cbmcfi1", - "diff": [ - { - "type": "delete", - "path": ["payload", "temp_rate"], - "from": null, - "to": null - } - ] - }, - { - "_id": "0000o3ocekq00achukuojpst03u3c9t4", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 8.270614506657845, - "to": 8.27061 - } - ] - }, - { - "_id": "0000orq7oc766e2i5tsps36ifpgq49vr", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 6.438867669612819, - "to": 6.43887 - } - ] - }, - { - "_id": "0000s092sqmi3uq1psma1s9tnojog436", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 9.87641966364939, - "to": 9.87642 - } - ] - }, - { - "_id": "0000ugjo3nbjdm43l67ckm1vksu7ha8i", - "diff": [ - { - "type": "delete", - "path": ["payload", "temp_rate"], - "from": null, - "to": null - } - ] - }, - { - "_id": "0000ushg75s767rrbuj34r9lgeppfm5m", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 7.382494828090559, - "to": 7.38249 - } - ] - }, - { - "_id": "0001394npef2cp1n2du0j0aon6m35va9", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 8.548151906210121, - "to": 8.54815 - } - ] - }, - { - "_id": "000141vp4hq535kmn55kj484chh1526f", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 11.157003462001523, - "to": 11.157 - } - ] - }, - { - "_id": "00018qlmsrs5vvs2ossvujrkgoq63ui6", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 6.050315310239632, - "to": 6.05032 - } - ] - }, - { - "_id": "0001gfdvg0sorbqcqmsvaeqatul4gr4r", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 8.659166866031033, - "to": 8.65917 - } - ] - }, - { - "_id": "0001k7kdh3quebrt74fht9q2estmq75i", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 8.992211745493764, - "to": 8.99221 - } - ] - }, - { - "_id": "0001nrq5d8r9thkk1badhc7sqv0b28dk", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 8.104092066926478, - "to": 8.10409 - } - ] - }, - { - "_id": "0001qgq51nngk6ubjel2c544frhch0eq", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 12.211645580300173, - "to": 12.21165 - } - ] - }, - { - "_id": "0001v81kcacfc9qhpvjmhr1ealooee2f", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 9.991346383881961, - "to": 9.99135 - } - ] - }, - { - "_id": "0001vqvo2jci3thogtb1ldbanc7t3euh", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 7.271479868269648, - "to": 7.27148 - } - ] - }, - { - "_id": "00020drvhoek75e31s2eb2ihr3hneab0", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 10.268883783434237, - "to": 10.26888 - } - ] - }, - { - "_id": "00021gjfc88sh2853sa9kvo8mibk3btb", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 6.1058227901500866, - "to": 6.10582 - } - ] - }, - { - "_id": "00022iu9mqq7vl22qg8cf27pl23mei6m", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 6.66089758925464, - "to": 6.6609 - } - ] - }, - { - "_id": "000272sak7skr78u235jvobkg2j2l7db", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 6.66089758925464, - "to": 6.6609 - } - ] - }, - { - "_id": "0002hhgscc8stmmgl56q2t5l4voag0k2", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 8.21510702674739, - "to": 8.21511 - } - ] - }, - { - "_id": "0002mvusipdajgceeghbmpcqo4ln3j2e", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 10.157868823613326, - "to": 10.15787 - } - ] - }, - { - "_id": "0002pqfv2solvi4lpuslibloq8n70egk", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 6.161330270060542, - "to": 6.16133 - } - ] - }, - { - "_id": "0002qi2gkb52qtljm471fqqfm360ir4k", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 11.601063301285166, - "to": 11.60106 - } - ] - }, - { - "_id": "0002sn9beaeh9j81v3djcbmapuftu23n", - "diff": [ - { - "type": "delete", - "path": ["payload", "temp_rate"], - "from": null, - "to": null - } - ] - }, - { - "_id": "0002tt08v467lkusp8dti02a1of7nq9f", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 7.549017267821926, - "to": 7.54902 - } - ] - }, - { - "_id": "0002umkmpa7atejb43k56ut0soqdq9jn", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 6.882927508896461, - "to": 6.88293 - } - ] - }, - { - "_id": "0002uu965smbnbp8uu95a21dmh270g67", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 6.938434988806917, - "to": 6.93843 - } - ] - }, - { - "_id": "0002vd9ik54eh1qrs4rinp3o6frt53pn", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 13.432810138330192, - "to": 13.43281 - } - ] - }, - { - "_id": "00030vvt9bf2fh3akggqko8e9hbk1gmp", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 8.548151906210121, - "to": 8.54815 - } - ] - }, - { - "_id": "00032090p27jjo7en5v81bc86sk500eg", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 5.7727779106873545, - "to": 5.77278 - } - ] - }, - { - "_id": "00032ph132hqdl11ljcosfs118opd6uj", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 4.16306099328415, - "to": 4.16306 - } - ] - }, - { - "_id": "000359urjliju7o3vhemciluk0b8go5h", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 6.272345229881453, - "to": 6.27235 - } - ] - }, - { - "_id": "00035k3g10h5s065fm7ujdkqsffdpefj", - "diff": [ - { - "type": "delete", - "path": ["payload", "temp_rate"], - "from": null, - "to": null - } - ] - }, - { - "_id": "00035qapsmj0g0tj5911j88861e1ja85", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 7.826554667374202, - "to": 7.82655 - } - ] - }, - { - "_id": "0003c7lqj9o23tk7mrf3ous8bqit32qn", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 8.21510702674739, - "to": 8.21511 - } - ] - }, - { - "_id": "0003eh53gp42t49i3p50rtn5t8nhrce5", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 4.829150752209614, - "to": 4.82915 - } - ] - }, - { - "_id": "0003f9b07hcfpfvl7o9mn49kg4sp89jg", - "diff": [ - { - "type": "delete", - "path": ["payload", "temp_rate"], - "from": null, - "to": null - } - ] - }, - { - "_id": "0003hf5lemo91skk3s64nvjqiolci7ca", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 8.437136946389211, - "to": 8.43714 - } - ] - }, - { - "_id": "0003i37c2j7llmbtkkja8td6p3cl72fm", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 12.211645580300173, - "to": 12.21165 - } - ] - }, - { - "_id": "0003jngv0eod115brtuua83d2kpu336a", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 10.990481022270156, - "to": 10.99048 - } - ] - }, - { - "_id": "0003k66j2k63js2kcamv5flmcftjv0vi", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 5.162195631672346, - "to": 5.1622 - } - ] - }, - { - "_id": "0003q61k26agdd8pputarp9tngnnl4bm", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 4.88465823212007, - "to": 4.88466 - } - ] - }, - { - "_id": "0003r9mmr8nbtkqn53b3ssucj6dnon3s", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 4.440598392836427, - "to": 4.4406 - } - ] - }, - { - "_id": "0003rgeeqhrgaljcvr0vn978mhh0urcr", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 5.550747991045533, - "to": 5.55075 - } - ] - }, - { - "_id": "0003sc9q9d2cgjblnbjpor1n5be4gdgq", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 6.383360189702364, - "to": 6.38336 - } - ] - }, - { - "_id": "0004b6tsha75kvbltqn36eqknhgpokj7", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 2.2202991964182135, - "to": 2.2203 - } - ] - }, - { - "_id": "0004etdb73eniso7uesle4ebv3unbmhk", - "diff": [ - { - "type": "delete", - "path": ["payload", "algorithm_rate"], - "from": null, - "to": null - }, - { - "type": "delete", - "path": ["payload", "temp_rate"], - "from": null, - "to": null - } - ] - }, - { - "_id": "0004h0iv775p64gu5p9bsgupfeng7rft", - "diff": [ - { - "type": "delete", - "path": ["payload", "temp_rate"], - "from": null, - "to": null - } - ] - }, - { - "_id": "0004hlsdjp3sm3ri89qma8nv6qcp5q3f", - "diff": [ - { - "type": "delete", - "path": ["payload", "temp_rate"], - "from": null, - "to": null - } - ] - }, - { - "_id": "0004jt901qccjhlukths98e2g6e3kn28", - "diff": [ - { - "type": "delete", - "path": ["payload", "temp_rate"], - "from": null, - "to": null - } - ] - }, - { - "_id": "0004rreii78v6da848mniincnb55qjkv", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 14.26542233698702, - "to": 14.26542 - } - ] - }, - { - "_id": "000556rqprsdce1g00gf3248ibduqns6", - "diff": [ - { - "type": "delete", - "path": ["payload", "temp_rate"], - "from": null, - "to": null - } - ] - }, - { - "_id": "00055b6nf17dpga93vi8d9npgja8oui2", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 7.049449948627828, - "to": 7.04945 - } - ] - }, - { - "_id": "000570t2klm76u0pge2fa1l6sb2vacou", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 4.829150752209614, - "to": 4.82915 - } - ] - }, - { - "_id": "0005jqjjc16r97d1j4kjsul8gv5s4m85", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 15.153542015554306, - "to": 15.15354 - } - ] - }, - { - "_id": "0005s07sgj51fi9tg30cdmbejdrtktva", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 10.82395858253879, - "to": 10.82396 - } - ] - }, - { - "_id": "0005uf2eav6074jqr9kfais0gdnufhv6", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 12.211645580300173, - "to": 12.21165 - } - ] - }, - { - "_id": "00065i6mgho4lk4ljel4iad1sh12ks6a", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 8.104092066926478, - "to": 8.10409 - } - ] - }, - { - "_id": "000662f21o6q6h563se5dh1bpuji1j8s", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 2.164791716507758, - "to": 2.16479 - } - ] - }, - { - "_id": "0006aji37fd7sn1abvdh14g5bu04cqa6", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 10.879466062449245, - "to": 10.87947 - } - ] - }, - { - "_id": "0006asj48h8inkrq03mudant3sqbm2j7", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 6.383360189702364, - "to": 6.38336 - } - ] - }, - { - "_id": "0006au8dsvu6590iv9oj828rd5p1u37e", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 8.104092066926478, - "to": 8.10409 - } - ] - }, - { - "_id": "0006iepb218jd1f51upa4o6fia8sklfp", - "diff": [ - { - "type": "delete", - "path": ["payload", "temp_rate"], - "from": null, - "to": null - } - ] - }, - { - "_id": "0006ighrh1qkbfmmqmg9s81vvvs9c8pd", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 7.382494828090559, - "to": 7.38249 - } - ] - }, - { - "_id": "0006j5vr2m5r55jcu5lt9looau2s71fm", - "diff": [ - { - "type": "delete", - "path": ["payload", "temp_rate"], - "from": null, - "to": null - } - ] - }, - { - "_id": "00000rnk44mf6pha8rmjb8mpiuipkdaa", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 4.88465823212007, - "to": 4.88466 - } - ] - }, - { - "_id": "00001jb82bd12eg0eca8k2c49ujfnk8l", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 8.104092066926478, - "to": 8.10409 - } - ] - }, - { - "_id": "00003sa2flpghjst5u4jnrt9kbt4dvlr", - "diff": [ - { - "type": "delete", - "path": ["payload", "temp_rate"], - "from": null, - "to": null - }, - { - "type": "delete", - "path": ["payload", "algorithm_rate"], - "from": null, - "to": null - } - ] - }, - { - "_id": "00009es5b8a4b4ee3v06f53df255hmpv", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 7.882062147284658, - "to": 7.88206 - } - ] - }, - { - "_id": "0000a6upv4rpd6n0am7t1uvlbe9snn4a", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 12.211645580300173, - "to": 12.21165 - } - ] - }, - { - "_id": "0000kr4f38gv49kep801vlj08cbmcfi1", - "diff": [ - { - "type": "delete", - "path": ["payload", "temp_rate"], - "from": null, - "to": null - } - ] - }, - { - "_id": "0000o3ocekq00achukuojpst03u3c9t4", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 8.270614506657845, - "to": 8.27061 - } - ] - }, - { - "_id": "0000orq7oc766e2i5tsps36ifpgq49vr", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 6.438867669612819, - "to": 6.43887 - } - ] - }, - { - "_id": "0000s092sqmi3uq1psma1s9tnojog436", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 9.87641966364939, - "to": 9.87642 - } - ] - }, - { - "_id": "0000ugjo3nbjdm43l67ckm1vksu7ha8i", - "diff": [ - { - "type": "delete", - "path": ["payload", "temp_rate"], - "from": null, - "to": null - } - ] - }, - { - "_id": "0000ushg75s767rrbuj34r9lgeppfm5m", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 7.382494828090559, - "to": 7.38249 - } - ] - }, - { - "_id": "0001394npef2cp1n2du0j0aon6m35va9", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 8.548151906210121, - "to": 8.54815 - } - ] - }, - { - "_id": "000141vp4hq535kmn55kj484chh1526f", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 11.157003462001523, - "to": 11.157 - } - ] - }, - { - "_id": "00018qlmsrs5vvs2ossvujrkgoq63ui6", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 6.050315310239632, - "to": 6.05032 - } - ] - }, - { - "_id": "0001gfdvg0sorbqcqmsvaeqatul4gr4r", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 8.659166866031033, - "to": 8.65917 - } - ] - }, - { - "_id": "0001k7kdh3quebrt74fht9q2estmq75i", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 8.992211745493764, - "to": 8.99221 - } - ] - }, - { - "_id": "0001nrq5d8r9thkk1badhc7sqv0b28dk", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 8.104092066926478, - "to": 8.10409 - } - ] - }, - { - "_id": "0001qgq51nngk6ubjel2c544frhch0eq", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 12.211645580300173, - "to": 12.21165 - } - ] - }, - { - "_id": "0001v81kcacfc9qhpvjmhr1ealooee2f", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 9.991346383881961, - "to": 9.99135 - } - ] - }, - { - "_id": "0001vqvo2jci3thogtb1ldbanc7t3euh", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 7.271479868269648, - "to": 7.27148 - } - ] - }, - { - "_id": "00020drvhoek75e31s2eb2ihr3hneab0", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 10.268883783434237, - "to": 10.26888 - } - ] - }, - { - "_id": "00021gjfc88sh2853sa9kvo8mibk3btb", - "diff": [ - { - "type": "update", - "path": ["value"], - "from": 6.1058227901500866, - "to": 6.10582 - } - ] - } -] diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 3e116edc87..412327651e 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -205,7 +205,7 @@ func BuildDatum(id string, objectData map[string]interface{}) (*data.Datum, erro return datum, nil } -func GetDifference(id string, datum interface{}, rawObject map[string]interface{}) ([]bson.M, error) { +func GetDifference(id string, datum interface{}, originalObject map[string]interface{}, log bool) ([]bson.M, error) { difference := []bson.M{} outgoingJSONData, err := json.Marshal(datum) if err != nil { @@ -217,17 +217,33 @@ func GetDifference(id string, datum interface{}, rawObject map[string]interface{ return nil, err } - // these are extras that we want to leave on the original object - // notRequired := []string{"_active", "_groupId", "_id", "_userId", "_version", "_schemaVersion", "_deduplicator", "uploadId", "createdTime", "guid", "modifiedTime", "_archivedTime"} - // for _, key := range notRequired { - // delete(rawObject, key) - // } + // these are extras that we want to leave on the + // original object so don't compare + notRequired := []string{ + "_active", + "_archivedTime", + "_deduplicator", + "_groupId", + "_id", + "_schemaVersion", + "_userId", + "_version", + "createdTime", + "guid", + "modifiedTime", + "payload", //hmmm unless we have converted it? + "uploadId", + } + + for _, key := range notRequired { + delete(originalObject, key) + delete(processedObject, key) + } - changelog, err := diff.Diff(rawObject, processedObject, diff.StructMapKeySupport()) + changelog, err := diff.Diff(originalObject, processedObject, diff.StructMapKeySupport()) if err != nil { return nil, err } - logDiff(id, changelog) set := bson.M{} unset := bson.M{} @@ -264,6 +280,11 @@ func GetDifference(id string, datum interface{}, rawObject map[string]interface{ if len(unset) > 0 { difference = append(difference, bson.M{"$unset": unset}) } + + if log { + logDiff(id, difference) + } + return difference, nil } @@ -289,7 +310,7 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { return nil, err } - difference, err := GetDifference(dID, datum, ojbData) + difference, err := GetDifference(dID, datum, ojbData, true) if err != nil { return nil, err } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index cd2f4730aa..00d7729208 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -185,31 +185,29 @@ var _ = Describe("back-37", func() { return rawObject } - //var pumpSettingsDatum *pump.Pump var incomingObject map[string]interface{} var datumObject bson.M BeforeEach(func() { datumObject = getBSONData(test.AutomatedBasalTandem) incomingObject = getRawData(test.AutomatedBasalTandem) - }) It("has no difference", func() { - diff, err := utils.GetDifference(expectedID, datumObject, incomingObject) + diff, err := utils.GetDifference(expectedID, datumObject, incomingObject, false) Expect(err).To(BeNil()) Expect(diff).ToNot(BeNil()) Expect(diff).To(Equal([]bson.M{})) }) It("set for missing properties", func() { delete(incomingObject, "deliveryType") - diff, err := utils.GetDifference(expectedID, datumObject, incomingObject) + diff, err := utils.GetDifference(expectedID, datumObject, incomingObject, false) Expect(err).To(BeNil()) Expect(diff).To(Equal([]bson.M{{"$set": bson.M{"deliveryType": "automated"}}})) }) It("unset for unwanted properties", func() { incomingObject["random"] = map[string]interface{}{"extra": true} - diff, err := utils.GetDifference(expectedID, datumObject, incomingObject) + diff, err := utils.GetDifference(expectedID, datumObject, incomingObject, false) Expect(err).To(BeNil()) Expect(diff).To(Equal([]bson.M{{"$unset": bson.M{"random": ""}}})) }) From 7011293ff11505aa0ba15f72ee050b17cecfcbc3 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 12 Feb 2024 13:54:33 +1300 Subject: [PATCH 187/413] import order --- .../20231128_jellyfish_migration/utils/utils.go | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 412327651e..27d8e3b001 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -9,29 +9,26 @@ import ( "strings" "time" + "github.com/r3labs/diff/v3" "go.mongodb.org/mongo-driver/bson" - "github.com/r3labs/diff/v3" "github.com/tidepool-org/platform/data" - "github.com/tidepool-org/platform/data/blood/glucose" "github.com/tidepool-org/platform/data/deduplicator/deduplicator" + dataNormalizer "github.com/tidepool-org/platform/data/normalizer" "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/data/types/basal" - "github.com/tidepool-org/platform/data/types/calculator" - "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" "github.com/tidepool-org/platform/data/types/blood/ketone" "github.com/tidepool-org/platform/data/types/bolus" + "github.com/tidepool-org/platform/data/types/calculator" "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/data/types/device" + dataTypesFactory "github.com/tidepool-org/platform/data/types/factory" "github.com/tidepool-org/platform/data/types/settings/pump" errorsP "github.com/tidepool-org/platform/errors" "github.com/tidepool-org/platform/metadata" - - dataNormalizer "github.com/tidepool-org/platform/data/normalizer" - dataTypesFactory "github.com/tidepool-org/platform/data/types/factory" structureParser "github.com/tidepool-org/platform/structure/parser" structureValidator "github.com/tidepool-org/platform/structure/validator" ) @@ -310,11 +307,10 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { return nil, err } - difference, err := GetDifference(dID, datum, ojbData, true) + _, err = GetDifference(dID, datum, ojbData, true) if err != nil { return nil, err } - log.Printf("diff: %v", difference) return *datum, nil } From 9a0548c8a945ada2dbfedef8ba33c73dc39df8ca Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 12 Feb 2024 14:43:14 +1300 Subject: [PATCH 188/413] remove payload --- migrations/20231128_jellyfish_migration/utils/utils.go | 1 - 1 file changed, 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 27d8e3b001..ae65acf499 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -228,7 +228,6 @@ func GetDifference(id string, datum interface{}, originalObject map[string]inter "createdTime", "guid", "modifiedTime", - "payload", //hmmm unless we have converted it? "uploadId", } From c27671a120338458fe856098c325b2da3f23438e Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 12 Feb 2024 14:57:49 +1300 Subject: [PATCH 189/413] check if cap set or not --- .../utils/migrationUtil.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 8cb6ce752e..ce854cbce9 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -107,10 +107,12 @@ func (m *migrationUtil) Initialize(ctx context.Context, dataC *mongo.Collection) } func (m *migrationUtil) capReached() bool { - stats := m.GetStats() - log.Printf("cap [%d] updated [%d] fetched [%d]", *m.config.cap, stats.Applied, stats.Fetched) - if *m.config.cap < stats.Applied || *m.config.cap < stats.Fetched { - return true + if m.config.cap != nil { + stats := m.GetStats() + log.Printf("cap [%d] updated [%d] fetched [%d]", *m.config.cap, stats.Applied, stats.Fetched) + if *m.config.cap <= stats.Applied || *m.config.cap <= stats.Fetched { + return true + } } return false } From c46998bb2af5cd95355a53596436b4fd2b07e68a Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 12 Feb 2024 16:30:50 +1300 Subject: [PATCH 190/413] set last update ID for select --- .../jellyfish_migration.go | 13 +++++++++++-- .../utils/utils.go | 18 +++++++----------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 7fd5122bdc..3e0c0b392b 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -317,10 +317,19 @@ func (m *Migration) fetchAndProcess() bool { log.Printf("error decoding data: %s", err) return false } - _, err := utils.ProcessDatum(item) + + itemID := fmt.Sprintf("%v", item["_id"]) + updates, err := utils.ProcessDatum(itemID, item) if err != nil { - m.migrationUtil.OnError(err, fmt.Sprintf("%v", item["_id"]), fmt.Sprintf("[type=%v]", item["type"])) + m.migrationUtil.OnError(err, itemID, fmt.Sprintf("[type=%v]", item["type"])) } + for _, update := range updates { + updateOp := mongo.NewUpdateOneModel() + updateOp.SetFilter(bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}) + updateOp.SetUpdate(update) + m.migrationUtil.SetUpdates(itemID, updateOp) + } + all = append(all, item) } m.migrationUtil.SetFetched(all) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index ae65acf499..7be6f5cbc3 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -172,13 +172,12 @@ func BuildDatum(id string, objectData map[string]interface{}) (*data.Datum, erro } validator.Bool("_active", parser.Bool("_active")).Exists() + validator.String("_archivedTime", parser.String("_archivedTime")) validator.String("_groupId", parser.String("_groupId")).Exists() validator.String("_id", parser.String("_id")).Exists() validator.String("_userId", parser.String("_userId")).Exists() validator.Int("_version", parser.Int("_version")).Exists() validator.Int("_schemaVersion", parser.Int("_schemaVersion")) - - validator.String("_archivedTime", parser.String("_archivedTime")) validator.Object("_deduplicator", parser.Object("_deduplicator")).Exists() validator.String("uploadId", parser.String("uploadId")).Exists() @@ -203,7 +202,7 @@ func BuildDatum(id string, objectData map[string]interface{}) (*data.Datum, erro } func GetDifference(id string, datum interface{}, originalObject map[string]interface{}, log bool) ([]bson.M, error) { - difference := []bson.M{} + outgoingJSONData, err := json.Marshal(datum) if err != nil { return nil, err @@ -267,6 +266,7 @@ func GetDifference(id string, datum interface{}, originalObject map[string]inter } } + difference := []bson.M{} if len(set) > 0 { difference = append(difference, bson.M{"$set": set}) } @@ -280,13 +280,10 @@ func GetDifference(id string, datum interface{}, originalObject map[string]inter if log { logDiff(id, difference) } - return difference, nil } -func ProcessDatum(bsonData bson.M) (data.Datum, error) { - - dID := fmt.Sprintf("%v", bsonData["_id"]) +func ProcessDatum(dataID string, bsonData bson.M) ([]bson.M, error) { if err := ApplyBaseChanges(bsonData); err != nil { return nil, err @@ -301,17 +298,16 @@ func ProcessDatum(bsonData bson.M) (data.Datum, error) { return nil, err } - datum, err := BuildDatum(dID, ojbData) + datum, err := BuildDatum(dataID, ojbData) if err != nil { return nil, err } - _, err = GetDifference(dID, datum, ojbData, true) + updates, err := GetDifference(dataID, datum, ojbData, true) if err != nil { return nil, err } - - return *datum, nil + return updates, nil } func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { From 4f6c7cf0d77897cfd3a72979205794826a0da123 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 12 Feb 2024 17:14:36 +1300 Subject: [PATCH 191/413] set id even when item not updated it has still been processed --- .../jellyfish_migration.go | 18 ++++++++++-------- .../utils/migrationUtil.go | 10 +++++++--- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 3e0c0b392b..99334aca26 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -258,7 +258,8 @@ func (m *Migration) fetchAndUpdateBatch() bool { updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": item["modifiedTime"]}) } updateOp.SetUpdate(update) - m.migrationUtil.SetUpdates(datumID, updateOp) + m.migrationUtil.SetUpdates(updateOp) + m.migrationUtil.SetLastProcessed(datumID) } } stats := m.migrationUtil.GetStats() @@ -322,14 +323,15 @@ func (m *Migration) fetchAndProcess() bool { updates, err := utils.ProcessDatum(itemID, item) if err != nil { m.migrationUtil.OnError(err, itemID, fmt.Sprintf("[type=%v]", item["type"])) + } else { + for _, update := range updates { + updateOp := mongo.NewUpdateOneModel() + updateOp.SetFilter(bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}) + updateOp.SetUpdate(update) + m.migrationUtil.SetUpdates(updateOp) + } } - for _, update := range updates { - updateOp := mongo.NewUpdateOneModel() - updateOp.SetFilter(bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}) - updateOp.SetUpdate(update) - m.migrationUtil.SetUpdates(itemID, updateOp) - } - + m.migrationUtil.SetLastProcessed(itemID) all = append(all, item) } m.migrationUtil.SetFetched(all) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index ce854cbce9..036ccab9d1 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -60,7 +60,8 @@ type MigrationUtil interface { Initialize(ctx context.Context, dataC *mongo.Collection) error Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func() bool) error OnError(reportErr error, id string, msg string) - SetUpdates(lastID string, update ...*mongo.UpdateOneModel) + SetUpdates(update ...*mongo.UpdateOneModel) + SetLastProcessed(lastID string) SetFetched(raw []bson.M) GetLastID() string GetStats() MigrationStats @@ -131,13 +132,16 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe return nil } -func (m *migrationUtil) SetUpdates(lastID string, update ...*mongo.UpdateOneModel) { - m.lastUpdatedId = lastID +func (m *migrationUtil) SetUpdates(update ...*mongo.UpdateOneModel) { for _, u := range update { m.updates = append(m.updates, u) } } +func (m *migrationUtil) SetLastProcessed(lastID string) { + m.lastUpdatedId = lastID +} + func (m *migrationUtil) SetFetched(raw []bson.M) { m.rawData = append(m.rawData, raw...) log.Printf("fetched [%d]", len(m.rawData)) From 9115b922c874ed2c941f40126d085f7b70517a78 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 12 Feb 2024 17:30:41 +1300 Subject: [PATCH 192/413] don't write the updates yet --- .../jellyfish_migration.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 99334aca26..1be12b7954 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -320,17 +320,19 @@ func (m *Migration) fetchAndProcess() bool { } itemID := fmt.Sprintf("%v", item["_id"]) - updates, err := utils.ProcessDatum(itemID, item) + _, err := utils.ProcessDatum(itemID, item) if err != nil { m.migrationUtil.OnError(err, itemID, fmt.Sprintf("[type=%v]", item["type"])) - } else { - for _, update := range updates { - updateOp := mongo.NewUpdateOneModel() - updateOp.SetFilter(bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}) - updateOp.SetUpdate(update) - m.migrationUtil.SetUpdates(updateOp) - } } + // TODO: process the updates + // } else { + // for _, update := range updates { + // updateOp := mongo.NewUpdateOneModel() + // updateOp.SetFilter(bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}) + // updateOp.SetUpdate(update) + // m.migrationUtil.SetUpdates(updateOp) + // } + // } m.migrationUtil.SetLastProcessed(itemID) all = append(all, item) } From 9c87b14e080b353aaf7ff02670e1a257286cca97 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 13 Feb 2024 08:29:13 +1300 Subject: [PATCH 193/413] switch to audit or update process --- .../jellyfish_migration.go | 190 +++--- .../utils/utils.go | 445 +++++++------ .../utils/utils_test.go | 622 +++++++++--------- 3 files changed, 631 insertions(+), 626 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 1be12b7954..0a8cc926db 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -6,7 +6,6 @@ import ( "log" "os" "strings" - "time" "github.com/urfave/cli" "go.mongodb.org/mongo-driver/bson" @@ -91,12 +90,14 @@ func (m *Migration) RunAndExit() { log.Printf("audit failed: %s", err) return err } - } else { - if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndUpdateBatch); err != nil { - log.Printf("execute failed: %s", err) - return err - } } + // TODO: switch to audit + update + // } else { + // if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndUpdateBatch); err != nil { + // log.Printf("execute failed: %s", err) + // return err + // } + // } return nil } @@ -194,83 +195,85 @@ func (m *Migration) getDataCollection() *mongo.Collection { return m.client.Database("data").Collection("deviceData") } -func (m *Migration) fetchAndUpdateBatch() bool { - - selector := bson.M{ - "_deduplicator": bson.M{"$exists": false}, - } - - if strings.TrimSpace(m.config.userID) != "" { - log.Printf("fetching for user %s", m.config.userID) - selector["_userId"] = m.config.userID - } - - // jellyfish uses a generated _id that is not an mongo objectId - idNotObjectID := bson.M{"$not": bson.M{"$type": "objectId"}} - - if lastID := m.migrationUtil.GetLastID(); lastID != "" { - selector["$and"] = []interface{}{ - bson.M{"_id": bson.M{"$gt": lastID}}, - bson.M{"_id": idNotObjectID}, - } - } else { - selector["_id"] = idNotObjectID - } - - batchSize := int32(m.config.queryBatchSize) - - if dataC := m.getDataCollection(); dataC != nil { - - dDataCursor, err := dataC.Find(m.ctx, selector, - &options.FindOptions{ - Sort: bson.M{"_id": 1}, - BatchSize: &batchSize, - Limit: &m.config.queryLimit, - }, - ) - if err != nil { - log.Printf("failed to select data: %s", err) - return false - } - defer dDataCursor.Close(m.ctx) - - updateStart := time.Now() - - for dDataCursor.Next(m.ctx) { - - item := bson.M{} - if err := dDataCursor.Decode(&item); err != nil { - log.Printf("error decoding data: %s", err) - return false - } - - datumID, datumUpdates, err := utils.GetDatumUpdates(item) - if err != nil { - m.migrationUtil.OnError(err, datumID, "failed applying updates") - continue - } - for _, update := range datumUpdates { - updateOp := mongo.NewUpdateOneModel() - if update["$rename"] != nil { - log.Printf("rename op, 2 ops for same datum") - updateOp.SetFilter(bson.M{"_id": datumID}) - } else { - updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": item["modifiedTime"]}) - } - updateOp.SetUpdate(update) - m.migrationUtil.SetUpdates(updateOp) - m.migrationUtil.SetLastProcessed(datumID) - } - } - stats := m.migrationUtil.GetStats() - if stats.Errored > 0 { - log.Printf("update took [%s] for [%d] items with [%d] errors", time.Since(updateStart), stats.ToApply, stats.Errored) - } - return stats.ToApply > 0 - } - return false -} - +// TODO: switch to audit + update +// func (m *Migration) fetchAndUpdateBatch() bool { + +// selector := bson.M{ +// "_deduplicator": bson.M{"$exists": false}, +// } + +// if strings.TrimSpace(m.config.userID) != "" { +// log.Printf("fetching for user %s", m.config.userID) +// selector["_userId"] = m.config.userID +// } + +// // jellyfish uses a generated _id that is not an mongo objectId +// idNotObjectID := bson.M{"$not": bson.M{"$type": "objectId"}} + +// if lastID := m.migrationUtil.GetLastID(); lastID != "" { +// selector["$and"] = []interface{}{ +// bson.M{"_id": bson.M{"$gt": lastID}}, +// bson.M{"_id": idNotObjectID}, +// } +// } else { +// selector["_id"] = idNotObjectID +// } + +// batchSize := int32(m.config.queryBatchSize) + +// if dataC := m.getDataCollection(); dataC != nil { + +// dDataCursor, err := dataC.Find(m.ctx, selector, +// &options.FindOptions{ +// Sort: bson.M{"_id": 1}, +// BatchSize: &batchSize, +// Limit: &m.config.queryLimit, +// }, +// ) +// if err != nil { +// log.Printf("failed to select data: %s", err) +// return false +// } +// defer dDataCursor.Close(m.ctx) + +// updateStart := time.Now() + +// for dDataCursor.Next(m.ctx) { + +// item := bson.M{} +// if err := dDataCursor.Decode(&item); err != nil { +// log.Printf("error decoding data: %s", err) +// return false +// } + +// datumID, datumUpdates, err := utils.GetDatumUpdates(item) +// if err != nil { +// m.migrationUtil.OnError(err, datumID, "failed applying updates") +// continue +// } +// for _, update := range datumUpdates { +// updateOp := mongo.NewUpdateOneModel() +// if update["$rename"] != nil { +// log.Printf("rename op, 2 ops for same datum") +// updateOp.SetFilter(bson.M{"_id": datumID}) +// } else { +// updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": item["modifiedTime"]}) +// } +// updateOp.SetUpdate(update) +// m.migrationUtil.SetUpdates(updateOp) +// m.migrationUtil.SetLastProcessed(datumID) +// } +// } +// stats := m.migrationUtil.GetStats() +// if stats.Errored > 0 { +// log.Printf("update took [%s] for [%d] items with [%d] errors", time.Since(updateStart), stats.ToApply, stats.Errored) +// } +// return stats.ToApply > 0 +// } +// return false +// } + +// TODO: switch to audit + update func (m *Migration) fetchAndProcess() bool { selector := bson.M{} @@ -312,27 +315,24 @@ func (m *Migration) fetchAndProcess() bool { all := []bson.M{} for dDataCursor.Next(m.ctx) { - item := bson.M{} if err := dDataCursor.Decode(&item); err != nil { log.Printf("error decoding data: %s", err) return false } - itemID := fmt.Sprintf("%v", item["_id"]) - _, err := utils.ProcessDatum(itemID, item) + updates, err := utils.ProcessDatum(itemID, item) if err != nil { m.migrationUtil.OnError(err, itemID, fmt.Sprintf("[type=%v]", item["type"])) } - // TODO: process the updates - // } else { - // for _, update := range updates { - // updateOp := mongo.NewUpdateOneModel() - // updateOp.SetFilter(bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}) - // updateOp.SetUpdate(update) - // m.migrationUtil.SetUpdates(updateOp) - // } - // } + if !m.config.audit { + for _, update := range updates { + updateOp := mongo.NewUpdateOneModel() + updateOp.SetFilter(bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}) + updateOp.SetUpdate(update) + m.migrationUtil.SetUpdates(updateOp) + } + } m.migrationUtil.SetLastProcessed(itemID) all = append(all, item) } diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 7be6f5cbc3..90256c966d 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -14,17 +14,13 @@ import ( "github.com/tidepool-org/platform/data" "github.com/tidepool-org/platform/data/blood/glucose" - "github.com/tidepool-org/platform/data/deduplicator/deduplicator" dataNormalizer "github.com/tidepool-org/platform/data/normalizer" - "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/data/types/basal" "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" "github.com/tidepool-org/platform/data/types/blood/ketone" - "github.com/tidepool-org/platform/data/types/bolus" "github.com/tidepool-org/platform/data/types/calculator" "github.com/tidepool-org/platform/data/types/common" - "github.com/tidepool-org/platform/data/types/device" dataTypesFactory "github.com/tidepool-org/platform/data/types/factory" "github.com/tidepool-org/platform/data/types/settings/pump" errorsP "github.com/tidepool-org/platform/errors" @@ -158,7 +154,7 @@ func ApplyBaseChanges(bsonData bson.M) error { return nil } -func BuildDatum(id string, objectData map[string]interface{}) (*data.Datum, error) { +func BuildPlatformDatum(id string, objectData map[string]interface{}) (*data.Datum, error) { parser := structureParser.NewObject(&objectData) validator := structureValidator.New() normalizer := dataNormalizer.New() @@ -198,10 +194,30 @@ func BuildDatum(id string, objectData map[string]interface{}) (*data.Datum, erro if err := normalizer.Error(); err != nil { return nil, err } + + // TODO set the hash + // fields, err := (*datum).IdentityFields() + // if err != nil { + // return nil, errorsP.Wrap(err, "unable to gather identity fields for datum") + // } + + // hash, err := deduplicator.GenerateIdentityHash(fields) + // if err != nil { + // return nil, errorsP.Wrap(err, "unable to generate identity hash for datum") + // } + + // deduplicator := (*datum).DeduplicatorDescriptor() + // if deduplicator == nil { + // deduplicator = data.NewDeduplicatorDescriptor() + // } + // deduplicator.Hash = pointer.FromString(hash) + + // (*datum).SetDeduplicatorDescriptor(deduplicator) + return datum, nil } -func GetDifference(id string, datum interface{}, originalObject map[string]interface{}, log bool) ([]bson.M, error) { +func GetDatumChanges(id string, datum interface{}, original map[string]interface{}, log bool) ([]bson.M, error) { outgoingJSONData, err := json.Marshal(datum) if err != nil { @@ -231,18 +247,17 @@ func GetDifference(id string, datum interface{}, originalObject map[string]inter } for _, key := range notRequired { - delete(originalObject, key) + delete(original, key) delete(processedObject, key) } - changelog, err := diff.Diff(originalObject, processedObject, diff.StructMapKeySupport()) + changelog, err := diff.Diff(original, processedObject, diff.StructMapKeySupport()) if err != nil { return nil, err } set := bson.M{} unset := bson.M{} - rename := bson.M{} // ["path","to","change"] // {path: {to: {change: true}}} @@ -257,12 +272,10 @@ func GetDifference(id string, datum interface{}, originalObject map[string]inter for _, change := range changelog { switch change.Type { - case diff.CREATE: + case diff.CREATE, diff.UPDATE: set[change.Path[0]] = getValue(change.Path, change.To) case diff.DELETE: unset[change.Path[0]] = getValue(change.Path, "") - case diff.UPDATE: - rename[change.Path[0]] = getValue(change.Path, change.To) } } @@ -270,13 +283,9 @@ func GetDifference(id string, datum interface{}, originalObject map[string]inter if len(set) > 0 { difference = append(difference, bson.M{"$set": set}) } - if len(rename) > 0 { - difference = append(difference, bson.M{"$rename": rename}) - } if len(unset) > 0 { difference = append(difference, bson.M{"$unset": unset}) } - if log { logDiff(id, difference) } @@ -298,215 +307,215 @@ func ProcessDatum(dataID string, bsonData bson.M) ([]bson.M, error) { return nil, err } - datum, err := BuildDatum(dataID, ojbData) + datum, err := BuildPlatformDatum(dataID, ojbData) if err != nil { return nil, err } - updates, err := GetDifference(dataID, datum, ojbData, true) + updates, err := GetDatumChanges(dataID, datum, ojbData, true) if err != nil { return nil, err } return updates, nil } -func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { - updates := []bson.M{} - set := bson.M{} - var rename bson.M - var identityFields []string - - datumID, ok := bsonData["_id"].(string) - if !ok { - return "", nil, errorsP.New("cannot get the datum id") - } - - datumType, ok := bsonData["type"].(string) - if !ok { - return datumID, nil, errorsP.New("cannot get the datum type") - } - - // TODO: based on discussions we want to ensure that these are the correct type - // even though we are not using them for the hash generation - delete(bsonData, "payload") - delete(bsonData, "annotations") - - switch datumType { - case basal.Type: - var datum *basal.Basal - dataBytes, err := bson.Marshal(bsonData) - if err != nil { - return datumID, nil, err - } - err = bson.Unmarshal(dataBytes, &datum) - if err != nil { - return datumID, nil, err - } - identityFields, err = datum.IdentityFields() - if err != nil { - return datumID, nil, err - } - case bolus.Type: - var datum *bolus.Bolus - dataBytes, err := bson.Marshal(bsonData) - if err != nil { - return datumID, nil, err - } - err = bson.Unmarshal(dataBytes, &datum) - if err != nil { - return datumID, nil, err - } - identityFields, err = datum.IdentityFields() - if err != nil { - return datumID, nil, err - } - case device.Type: - var datum bolus.Bolus - dataBytes, err := bson.Marshal(bsonData) - if err != nil { - return datumID, nil, err - } - err = bson.Unmarshal(dataBytes, &datum) - if err != nil { - return datumID, nil, err - } - identityFields, err = datum.IdentityFields() - if err != nil { - return datumID, nil, err - } - case pump.Type: - var datum types.Base - dataBytes, err := bson.Marshal(bsonData) - if err != nil { - return datumID, nil, err - } - err = bson.Unmarshal(dataBytes, &datum) - if err != nil { - return datumID, nil, err - } - identityFields, err = datum.IdentityFields() - if err != nil { - return datumID, nil, err - } - - if pumpSettingsHasBolus(bsonData) { - rename = bson.M{"bolus": "boluses"} - } - - sleepSchedules, err := updateIfExistsPumpSettingsSleepSchedules(bsonData) - if err != nil { - return datumID, nil, err - } else if sleepSchedules != nil { - set["sleepSchedules"] = sleepSchedules - } - case selfmonitored.Type: - var datum selfmonitored.SelfMonitored - dataBytes, err := bson.Marshal(bsonData) - if err != nil { - return datumID, nil, err - } - err = bson.Unmarshal(dataBytes, &datum) - if err != nil { - return datumID, nil, err - } - beforeVal := datum.Value - beforeUnits := datum.Units - datum.Normalize(dataNormalizer.New()) - afterVal := datum.Value - afterUnits := datum.Units - if *beforeVal != *afterVal { - set["value"] = afterVal - } - if *beforeUnits != *afterUnits { - set["units"] = afterUnits - } - identityFields, err = datum.IdentityFields() - if err != nil { - return datumID, nil, err - } - case ketone.Type: - var datum ketone.Ketone - dataBytes, err := bson.Marshal(bsonData) - if err != nil { - return datumID, nil, err - } - err = bson.Unmarshal(dataBytes, &datum) - if err != nil { - return datumID, nil, err - } - beforeVal := datum.Value - beforeUnits := datum.Units - datum.Normalize(dataNormalizer.New()) - afterVal := datum.Value - afterUnits := datum.Units - if *beforeVal != *afterVal { - set["value"] = afterVal - } - if *beforeUnits != *afterUnits { - set["units"] = afterUnits - } - identityFields, err = datum.IdentityFields() - if err != nil { - return datumID, nil, err - } - case continuous.Type: - var datum continuous.Continuous - dataBytes, err := bson.Marshal(bsonData) - if err != nil { - return datumID, nil, err - } - err = bson.Unmarshal(dataBytes, &datum) - if err != nil { - return datumID, nil, err - } - // NOTE: applies to any type that has a `Glucose` property - // we need to normalise so that we can get the correct `Units`` and `Value`` precsion that we would if ingested via the platform. - // as these are both being used in the hash calc via the IdentityFields we want to persist these changes if they are infact updated. - beforeVal := datum.Value - beforeUnits := datum.Units - datum.Normalize(dataNormalizer.New()) - afterVal := datum.Value - afterUnits := datum.Units - if *beforeVal != *afterVal { - set["value"] = afterVal - } - if *beforeUnits != *afterUnits { - set["units"] = afterUnits - } - identityFields, err = datum.IdentityFields() - if err != nil { - return datumID, nil, err - } - default: - var datum types.Base - dataBytes, err := bson.Marshal(bsonData) - if err != nil { - return datumID, nil, err - } - err = bson.Unmarshal(dataBytes, &datum) - if err != nil { - return datumID, nil, err - } - identityFields, err = datum.IdentityFields() - if err != nil { - return datumID, nil, err - } - } - - hash, err := deduplicator.GenerateIdentityHash(identityFields) - if err != nil { - return datumID, nil, err - } - - set["_deduplicator"] = bson.M{"hash": hash} - - updates = append(updates, bson.M{"$set": set}) - if rename != nil { - log.Printf("rename %v", rename) - updates = append(updates, bson.M{"$rename": rename}) - } - if len(updates) != 1 { - log.Printf("datum updates %d", len(updates)) - } - return datumID, updates, nil -} +// func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { +// updates := []bson.M{} +// set := bson.M{} +// var rename bson.M +// var identityFields []string + +// datumID, ok := bsonData["_id"].(string) +// if !ok { +// return "", nil, errorsP.New("cannot get the datum id") +// } + +// datumType, ok := bsonData["type"].(string) +// if !ok { +// return datumID, nil, errorsP.New("cannot get the datum type") +// } + +// // TODO: based on discussions we want to ensure that these are the correct type +// // even though we are not using them for the hash generation +// delete(bsonData, "payload") +// delete(bsonData, "annotations") + +// switch datumType { +// case basal.Type: +// var datum *basal.Basal +// dataBytes, err := bson.Marshal(bsonData) +// if err != nil { +// return datumID, nil, err +// } +// err = bson.Unmarshal(dataBytes, &datum) +// if err != nil { +// return datumID, nil, err +// } +// identityFields, err = datum.IdentityFields() +// if err != nil { +// return datumID, nil, err +// } +// case bolus.Type: +// var datum *bolus.Bolus +// dataBytes, err := bson.Marshal(bsonData) +// if err != nil { +// return datumID, nil, err +// } +// err = bson.Unmarshal(dataBytes, &datum) +// if err != nil { +// return datumID, nil, err +// } +// identityFields, err = datum.IdentityFields() +// if err != nil { +// return datumID, nil, err +// } +// case device.Type: +// var datum bolus.Bolus +// dataBytes, err := bson.Marshal(bsonData) +// if err != nil { +// return datumID, nil, err +// } +// err = bson.Unmarshal(dataBytes, &datum) +// if err != nil { +// return datumID, nil, err +// } +// identityFields, err = datum.IdentityFields() +// if err != nil { +// return datumID, nil, err +// } +// case pump.Type: +// var datum types.Base +// dataBytes, err := bson.Marshal(bsonData) +// if err != nil { +// return datumID, nil, err +// } +// err = bson.Unmarshal(dataBytes, &datum) +// if err != nil { +// return datumID, nil, err +// } +// identityFields, err = datum.IdentityFields() +// if err != nil { +// return datumID, nil, err +// } + +// if pumpSettingsHasBolus(bsonData) { +// rename = bson.M{"bolus": "boluses"} +// } + +// sleepSchedules, err := updateIfExistsPumpSettingsSleepSchedules(bsonData) +// if err != nil { +// return datumID, nil, err +// } else if sleepSchedules != nil { +// set["sleepSchedules"] = sleepSchedules +// } +// case selfmonitored.Type: +// var datum selfmonitored.SelfMonitored +// dataBytes, err := bson.Marshal(bsonData) +// if err != nil { +// return datumID, nil, err +// } +// err = bson.Unmarshal(dataBytes, &datum) +// if err != nil { +// return datumID, nil, err +// } +// beforeVal := datum.Value +// beforeUnits := datum.Units +// datum.Normalize(dataNormalizer.New()) +// afterVal := datum.Value +// afterUnits := datum.Units +// if *beforeVal != *afterVal { +// set["value"] = afterVal +// } +// if *beforeUnits != *afterUnits { +// set["units"] = afterUnits +// } +// identityFields, err = datum.IdentityFields() +// if err != nil { +// return datumID, nil, err +// } +// case ketone.Type: +// var datum ketone.Ketone +// dataBytes, err := bson.Marshal(bsonData) +// if err != nil { +// return datumID, nil, err +// } +// err = bson.Unmarshal(dataBytes, &datum) +// if err != nil { +// return datumID, nil, err +// } +// beforeVal := datum.Value +// beforeUnits := datum.Units +// datum.Normalize(dataNormalizer.New()) +// afterVal := datum.Value +// afterUnits := datum.Units +// if *beforeVal != *afterVal { +// set["value"] = afterVal +// } +// if *beforeUnits != *afterUnits { +// set["units"] = afterUnits +// } +// identityFields, err = datum.IdentityFields() +// if err != nil { +// return datumID, nil, err +// } +// case continuous.Type: +// var datum continuous.Continuous +// dataBytes, err := bson.Marshal(bsonData) +// if err != nil { +// return datumID, nil, err +// } +// err = bson.Unmarshal(dataBytes, &datum) +// if err != nil { +// return datumID, nil, err +// } +// // NOTE: applies to any type that has a `Glucose` property +// // we need to normalise so that we can get the correct `Units`` and `Value`` precsion that we would if ingested via the platform. +// // as these are both being used in the hash calc via the IdentityFields we want to persist these changes if they are infact updated. +// beforeVal := datum.Value +// beforeUnits := datum.Units +// datum.Normalize(dataNormalizer.New()) +// afterVal := datum.Value +// afterUnits := datum.Units +// if *beforeVal != *afterVal { +// set["value"] = afterVal +// } +// if *beforeUnits != *afterUnits { +// set["units"] = afterUnits +// } +// identityFields, err = datum.IdentityFields() +// if err != nil { +// return datumID, nil, err +// } +// default: +// var datum types.Base +// dataBytes, err := bson.Marshal(bsonData) +// if err != nil { +// return datumID, nil, err +// } +// err = bson.Unmarshal(dataBytes, &datum) +// if err != nil { +// return datumID, nil, err +// } +// identityFields, err = datum.IdentityFields() +// if err != nil { +// return datumID, nil, err +// } +// } + +// hash, err := deduplicator.GenerateIdentityHash(identityFields) +// if err != nil { +// return datumID, nil, err +// } + +// set["_deduplicator"] = bson.M{"hash": hash} + +// updates = append(updates, bson.M{"$set": set}) +// if rename != nil { +// log.Printf("rename %v", rename) +// updates = append(updates, bson.M{"$rename": rename}) +// } +// if len(updates) != 1 { +// log.Printf("datum updates %d", len(updates)) +// } +// return datumID, updates, nil +// } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 00d7729208..36d90f89b2 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -3,7 +3,6 @@ package utils_test import ( "encoding/json" "fmt" - "strings" "time" . "github.com/onsi/ginkgo/v2" @@ -12,11 +11,8 @@ import ( "go.mongodb.org/mongo-driver/bson/primitive" "github.com/tidepool-org/platform/data/blood/glucose" - "github.com/tidepool-org/platform/data/normalizer" "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" glucoseTest "github.com/tidepool-org/platform/data/types/blood/glucose/test" - bolusTest "github.com/tidepool-org/platform/data/types/bolus/test" - "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/data/types/settings/pump" pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" @@ -25,7 +21,6 @@ import ( metadataTest "github.com/tidepool-org/platform/metadata/test" "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils/test" - "github.com/tidepool-org/platform/pointer" ) var _ = Describe("back-37", func() { @@ -194,329 +189,330 @@ var _ = Describe("back-37", func() { }) It("has no difference", func() { - diff, err := utils.GetDifference(expectedID, datumObject, incomingObject, false) + diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject, false) Expect(err).To(BeNil()) Expect(diff).ToNot(BeNil()) Expect(diff).To(Equal([]bson.M{})) }) It("set for missing properties", func() { delete(incomingObject, "deliveryType") - diff, err := utils.GetDifference(expectedID, datumObject, incomingObject, false) + diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject, false) Expect(err).To(BeNil()) Expect(diff).To(Equal([]bson.M{{"$set": bson.M{"deliveryType": "automated"}}})) }) It("unset for unwanted properties", func() { incomingObject["random"] = map[string]interface{}{"extra": true} - diff, err := utils.GetDifference(expectedID, datumObject, incomingObject, false) + diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject, false) Expect(err).To(BeNil()) Expect(diff).To(Equal([]bson.M{{"$unset": bson.M{"random": ""}}})) }) }) - var _ = Describe("GetDatumUpdates", func() { - var existingBolusDatum bson.M - const expectedID = "some-id" - - var getBSONData = func(datum interface{}) bson.M { - var bsonData bson.M - bsonAsByte, _ := bson.Marshal(&datum) - bson.Unmarshal(bsonAsByte, &bsonData) - return bsonData - } - - BeforeEach(func() { - datum := bolusTest.RandomBolus() - *datum.ID = expectedID - *datum.UserID = "some-user-id" - *datum.DeviceID = "some-device-id" - datum.SubType = "some-subtype" - theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") - *datum.Time = theTime - existingBolusDatum = getBSONData(datum) - existingBolusDatum["_id"] = expectedID - Expect(existingBolusDatum).ToNot(BeNil()) - }) - - Context("_deduplicator hash", func() { - DescribeTable("should", - func(getInput func() bson.M, expectedUpdates []bson.M, expectError bool) { - input := getInput() - actualID, actualUpdates, err := utils.GetDatumUpdates(input) - if expectError { - Expect(err).ToNot(BeNil()) - Expect(actualUpdates).To(BeNil()) - return - } - Expect(err).To(BeNil()) - if expectedUpdates != nil { - Expect(actualUpdates).To(Equal(expectedUpdates)) - Expect(actualID).To(Equal(expectedID)) - } else { - Expect(actualUpdates).To(BeNil()) - } - }, - Entry("error when missing _userId", func() bson.M { - existingBolusDatum["_userId"] = nil - return existingBolusDatum - }, nil, true), - Entry("error when missing deviceId", func() bson.M { - existingBolusDatum["deviceId"] = nil - return existingBolusDatum - }, nil, true), - Entry("error when missing time", func() bson.M { - existingBolusDatum["time"] = nil - return existingBolusDatum - }, nil, true), - Entry("error when missing type", func() bson.M { - existingBolusDatum["type"] = nil - return existingBolusDatum - }, nil, true), - Entry("adds hash when vaild", func() bson.M { - return existingBolusDatum - }, - []bson.M{ - {"$set": bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}}, - }, - false, - ), - ) - }) - - Context("pumpSettings", func() { - - var pumpSettingsDatum *pump.Pump - - BeforeEach(func() { - mmolL := pump.DisplayBloodGlucoseUnitsMmolPerL - pumpSettingsDatum = pumpTest.NewPump(&mmolL) - *pumpSettingsDatum.ID = expectedID - *pumpSettingsDatum.UserID = "some-user-id" - *pumpSettingsDatum.DeviceID = "some-device-id" - theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") - *pumpSettingsDatum.Time = theTime - }) - - Context("with mis-named jellyfish bolus", func() { - var bolusData = &pump.BolusMap{ - "bolus-1": pumpTest.NewRandomBolus(), - "bolus-2": pumpTest.NewRandomBolus(), - } - var settingsBolusDatum bson.M - - BeforeEach(func() { - settingsBolusDatum = getBSONData(pumpSettingsDatum) - settingsBolusDatum["bolus"] = bolusData - settingsBolusDatum["_id"] = expectedID - }) - - DescribeTable("should", - func(getInput func() bson.M, expected []bson.M, expectError bool) { - input := getInput() - _, actual, err := utils.GetDatumUpdates(input) - if expectError { - Expect(err).ToNot(BeNil()) - Expect(actual).To(BeNil()) - return - } - Expect(err).To(BeNil()) - if expected != nil { - Expect(actual).To(BeEquivalentTo(expected)) - } else { - Expect(actual).To(BeNil()) - } - }, - - Entry("do nothing when wrong type", - func() bson.M { - return existingBolusDatum - }, - []bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}}}, - false, - ), - Entry("do nothing when has no bolus", - func() bson.M { - settingsBolusDatum["bolus"] = nil - return settingsBolusDatum - }, - []bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}}}, - false, - ), - Entry("add boluses when bolus found", - func() bson.M { - settingsBolusDatum["bolus"] = bolusData - return settingsBolusDatum - }, - []bson.M{ - {"$set": bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}}, - {"$rename": bson.M{"bolus": "boluses"}}, - }, - false, - ), - ) - }) - Context("unordered sleepSchedules", func() { - expectedSleepSchedulesMap := &pump.SleepScheduleMap{} - var invalidDays *pump.SleepSchedule - var s1Days *pump.SleepSchedule - var s2Days *pump.SleepSchedule - var sleepSchedulesDatum bson.M - BeforeEach(func() { - s1 := pumpTest.RandomSleepSchedule() - s2 := pumpTest.RandomSleepSchedule() - (*expectedSleepSchedulesMap)["1"] = s1 - (*expectedSleepSchedulesMap)["2"] = s2 - - s1Days = pumpTest.CloneSleepSchedule(s1) - for key, day := range *s1Days.Days { - (*s1Days.Days)[key] = strings.ToUpper(day) - } - s2Days = pumpTest.CloneSleepSchedule(s2) - for key, day := range *s2Days.Days { - (*s2Days.Days)[key] = strings.ToUpper(day) - } - invalidDays = pumpTest.CloneSleepSchedule(s2) - invalidDays.Days = &[]string{"not-a-day", common.DayFriday} - - //to ensure correct sorting - expectedSleepSchedulesMap.Normalize(normalizer.New()) - - Expect(expectedSleepSchedulesMap).ToNot(BeNil()) - pumpSettingsDatum.SleepSchedules = nil - sleepSchedulesDatum = getBSONData(pumpSettingsDatum) - sleepSchedulesDatum["_id"] = expectedID - sleepSchedulesDatum["bolus"] = nil //remove as not testing here - }) - - It("does nothing when wrong type", func() { - _, actual, err := utils.GetDatumUpdates(existingBolusDatum) - Expect(err).To(BeNil()) - Expect(len(actual)).To(Equal(1)) - Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}}})) - }) - It("does nothing when no sleepSchedules", func() { - sleepSchedulesDatum["sleepSchedules"] = nil - _, actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) - Expect(err).To(BeNil()) - Expect(len(actual)).To(Equal(1)) - Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}}})) - }) - It("returns updated sleepSchedules when valid", func() { - sleepSchedulesDatum["sleepSchedules"] = []*pump.SleepSchedule{s1Days, s2Days} - _, actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) - Expect(err).To(BeNil()) - Expect(len(actual)).To(Equal(1)) - setData := actual[0]["$set"].(bson.M) - Expect(setData["sleepSchedules"]).ToNot(BeNil()) - Expect(setData["sleepSchedules"]).To(Equal(expectedSleepSchedulesMap)) - }) - It("returns error when sleepSchedules have invalid days", func() { - sleepSchedulesDatum["sleepSchedules"] = []*pump.SleepSchedule{invalidDays} - _, actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) - Expect(err).ToNot(BeNil()) - Expect(err.Error()).To(Equal("pumpSettings.sleepSchedules has an invalid day of week not-a-day")) - Expect(actual).To(BeNil()) - }) - }) - }) - Context("datum with glucose", func() { - - var newContinuous = func(units *string) *continuous.Continuous { - datum := continuous.New() - datum.Glucose = *glucoseTest.NewGlucose(units) - datum.Type = "cbg" - *datum.ID = expectedID - *datum.UserID = "some-user-id" - *datum.DeviceID = "some-device-id" - theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") - *datum.Time = theTime - return datum - } - - DescribeTable("should", - func(getInput func() bson.M, expected []bson.M, expectError bool) { - input := getInput() - _, actual, err := utils.GetDatumUpdates(input) - if expectError { - Expect(err).ToNot(BeNil()) - Expect(actual).To(BeNil()) - return - } - Expect(err).To(BeNil()) - if expected != nil { - Expect(actual).To(BeEquivalentTo(expected)) - } else { - Expect(actual).To(BeNil()) - } - }, - - Entry("do nothing when not normailzed", - func() bson.M { - mmolL := glucose.MmolL - cbg := newContinuous(&mmolL) - cbgData := getBSONData(cbg) - cbgData["_id"] = expectedID - cbgData["value"] = 9.5 - return cbgData - }, - []bson.M{{"$set": bson.M{ - "_deduplicator": bson.M{"hash": "lLCOZJMLvNaBx7dMc31bbX4zwSfPvxcUd0Z1uU/YIAs="}, - }}}, - false, - ), - Entry("update value when normailzed", - func() bson.M { - mgdL := glucose.MgdL - cbg := newContinuous(&mgdL) - cbgData := getBSONData(cbg) - cbgData["_id"] = expectedID - cbgData["value"] = 180 - - return cbgData - }, - []bson.M{{"$set": bson.M{ - "_deduplicator": bson.M{"hash": "FZtVRkliues5vAt25ZK+WDAqa4Q6tAAe9h2PdKM15Q4="}, - "value": pointer.FromFloat64(9.99135), - "units": pointer.FromString(glucose.MmolL), - }}}, - false, - ), - ) - }) - Context("Historic datum", func() { - It("g5 dexcom", func() { - actualID, actual, err := utils.GetDatumUpdates(getBSONData(test.CBGDexcomG5MobDatum)) - Expect(err).To(BeNil()) - Expect(actual).ToNot(BeNil()) - Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "TKJurm+/SuA5tarn/nATa7Nw0LXgwGel67lgJihUctM="}}}})) - Expect(actualID).ToNot(BeEmpty()) - }) - - It("carelink medtronic pumpSettings", func() { - actualID, actual, err := utils.GetDatumUpdates(getBSONData(test.PumpSettingsCarelink)) - Expect(err).To(BeNil()) - Expect(actual).ToNot(BeNil()) - Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "NC17pw1UAaab50iChhQXJ+N9dTi6GduTy9UjsMHolow="}}}})) - Expect(actualID).ToNot(BeEmpty()) - }) - - It("tandem pumpSettings", func() { - actualID, actual, err := utils.GetDatumUpdates(getBSONData(test.PumpSettingsTandem)) - Expect(err).To(BeNil()) - Expect(actual).ToNot(BeNil()) - Expect(len(actual)).To(Equal(1)) - Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "bpKLJbi5JfqD7N0WJ1vj0ck03c9EZ3U0H09TCLhdd3k="}}}})) - Expect(actualID).ToNot(BeEmpty()) - }) - - It("omnipod pumpSettings", func() { - actualID, actual, err := utils.GetDatumUpdates(getBSONData(test.PumpSettingsOmnipod)) - Expect(err).To(BeNil()) - Expect(actual).ToNot(BeNil()) - Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "oH7/6EEgUjRTeafEpm74fVTYMBvMdQ65/rhg0oFoev8="}}}})) - Expect(actualID).ToNot(BeEmpty()) - }) - - }) - }) + // TODO: switch to audit + update + // var _ = Describe("GetDatumUpdates", func() { + // var existingBolusDatum bson.M + // const expectedID = "some-id" + + // var getBSONData = func(datum interface{}) bson.M { + // var bsonData bson.M + // bsonAsByte, _ := bson.Marshal(&datum) + // bson.Unmarshal(bsonAsByte, &bsonData) + // return bsonData + // } + + // BeforeEach(func() { + // datum := bolusTest.RandomBolus() + // *datum.ID = expectedID + // *datum.UserID = "some-user-id" + // *datum.DeviceID = "some-device-id" + // datum.SubType = "some-subtype" + // theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") + // *datum.Time = theTime + // existingBolusDatum = getBSONData(datum) + // existingBolusDatum["_id"] = expectedID + // Expect(existingBolusDatum).ToNot(BeNil()) + // }) + + // Context("_deduplicator hash", func() { + // DescribeTable("should", + // func(getInput func() bson.M, expectedUpdates []bson.M, expectError bool) { + // input := getInput() + // actualID, actualUpdates, err := utils.GetDatumUpdates(input) + // if expectError { + // Expect(err).ToNot(BeNil()) + // Expect(actualUpdates).To(BeNil()) + // return + // } + // Expect(err).To(BeNil()) + // if expectedUpdates != nil { + // Expect(actualUpdates).To(Equal(expectedUpdates)) + // Expect(actualID).To(Equal(expectedID)) + // } else { + // Expect(actualUpdates).To(BeNil()) + // } + // }, + // Entry("error when missing _userId", func() bson.M { + // existingBolusDatum["_userId"] = nil + // return existingBolusDatum + // }, nil, true), + // Entry("error when missing deviceId", func() bson.M { + // existingBolusDatum["deviceId"] = nil + // return existingBolusDatum + // }, nil, true), + // Entry("error when missing time", func() bson.M { + // existingBolusDatum["time"] = nil + // return existingBolusDatum + // }, nil, true), + // Entry("error when missing type", func() bson.M { + // existingBolusDatum["type"] = nil + // return existingBolusDatum + // }, nil, true), + // Entry("adds hash when vaild", func() bson.M { + // return existingBolusDatum + // }, + // []bson.M{ + // {"$set": bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}}, + // }, + // false, + // ), + // ) + // }) + + // Context("pumpSettings", func() { + + // var pumpSettingsDatum *pump.Pump + + // BeforeEach(func() { + // mmolL := pump.DisplayBloodGlucoseUnitsMmolPerL + // pumpSettingsDatum = pumpTest.NewPump(&mmolL) + // *pumpSettingsDatum.ID = expectedID + // *pumpSettingsDatum.UserID = "some-user-id" + // *pumpSettingsDatum.DeviceID = "some-device-id" + // theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") + // *pumpSettingsDatum.Time = theTime + // }) + + // Context("with mis-named jellyfish bolus", func() { + // var bolusData = &pump.BolusMap{ + // "bolus-1": pumpTest.NewRandomBolus(), + // "bolus-2": pumpTest.NewRandomBolus(), + // } + // var settingsBolusDatum bson.M + + // BeforeEach(func() { + // settingsBolusDatum = getBSONData(pumpSettingsDatum) + // settingsBolusDatum["bolus"] = bolusData + // settingsBolusDatum["_id"] = expectedID + // }) + + // DescribeTable("should", + // func(getInput func() bson.M, expected []bson.M, expectError bool) { + // input := getInput() + // _, actual, err := utils.GetDatumUpdates(input) + // if expectError { + // Expect(err).ToNot(BeNil()) + // Expect(actual).To(BeNil()) + // return + // } + // Expect(err).To(BeNil()) + // if expected != nil { + // Expect(actual).To(BeEquivalentTo(expected)) + // } else { + // Expect(actual).To(BeNil()) + // } + // }, + + // Entry("do nothing when wrong type", + // func() bson.M { + // return existingBolusDatum + // }, + // []bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}}}, + // false, + // ), + // Entry("do nothing when has no bolus", + // func() bson.M { + // settingsBolusDatum["bolus"] = nil + // return settingsBolusDatum + // }, + // []bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}}}, + // false, + // ), + // Entry("add boluses when bolus found", + // func() bson.M { + // settingsBolusDatum["bolus"] = bolusData + // return settingsBolusDatum + // }, + // []bson.M{ + // {"$set": bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}}, + // {"$rename": bson.M{"bolus": "boluses"}}, + // }, + // false, + // ), + // ) + // }) + // Context("unordered sleepSchedules", func() { + // expectedSleepSchedulesMap := &pump.SleepScheduleMap{} + // var invalidDays *pump.SleepSchedule + // var s1Days *pump.SleepSchedule + // var s2Days *pump.SleepSchedule + // var sleepSchedulesDatum bson.M + // BeforeEach(func() { + // s1 := pumpTest.RandomSleepSchedule() + // s2 := pumpTest.RandomSleepSchedule() + // (*expectedSleepSchedulesMap)["1"] = s1 + // (*expectedSleepSchedulesMap)["2"] = s2 + + // s1Days = pumpTest.CloneSleepSchedule(s1) + // for key, day := range *s1Days.Days { + // (*s1Days.Days)[key] = strings.ToUpper(day) + // } + // s2Days = pumpTest.CloneSleepSchedule(s2) + // for key, day := range *s2Days.Days { + // (*s2Days.Days)[key] = strings.ToUpper(day) + // } + // invalidDays = pumpTest.CloneSleepSchedule(s2) + // invalidDays.Days = &[]string{"not-a-day", common.DayFriday} + + // //to ensure correct sorting + // expectedSleepSchedulesMap.Normalize(normalizer.New()) + + // Expect(expectedSleepSchedulesMap).ToNot(BeNil()) + // pumpSettingsDatum.SleepSchedules = nil + // sleepSchedulesDatum = getBSONData(pumpSettingsDatum) + // sleepSchedulesDatum["_id"] = expectedID + // sleepSchedulesDatum["bolus"] = nil //remove as not testing here + // }) + + // It("does nothing when wrong type", func() { + // _, actual, err := utils.GetDatumUpdates(existingBolusDatum) + // Expect(err).To(BeNil()) + // Expect(len(actual)).To(Equal(1)) + // Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}}})) + // }) + // It("does nothing when no sleepSchedules", func() { + // sleepSchedulesDatum["sleepSchedules"] = nil + // _, actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) + // Expect(err).To(BeNil()) + // Expect(len(actual)).To(Equal(1)) + // Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}}})) + // }) + // It("returns updated sleepSchedules when valid", func() { + // sleepSchedulesDatum["sleepSchedules"] = []*pump.SleepSchedule{s1Days, s2Days} + // _, actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) + // Expect(err).To(BeNil()) + // Expect(len(actual)).To(Equal(1)) + // setData := actual[0]["$set"].(bson.M) + // Expect(setData["sleepSchedules"]).ToNot(BeNil()) + // Expect(setData["sleepSchedules"]).To(Equal(expectedSleepSchedulesMap)) + // }) + // It("returns error when sleepSchedules have invalid days", func() { + // sleepSchedulesDatum["sleepSchedules"] = []*pump.SleepSchedule{invalidDays} + // _, actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) + // Expect(err).ToNot(BeNil()) + // Expect(err.Error()).To(Equal("pumpSettings.sleepSchedules has an invalid day of week not-a-day")) + // Expect(actual).To(BeNil()) + // }) + // }) + // }) + // Context("datum with glucose", func() { + + // var newContinuous = func(units *string) *continuous.Continuous { + // datum := continuous.New() + // datum.Glucose = *glucoseTest.NewGlucose(units) + // datum.Type = "cbg" + // *datum.ID = expectedID + // *datum.UserID = "some-user-id" + // *datum.DeviceID = "some-device-id" + // theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") + // *datum.Time = theTime + // return datum + // } + + // DescribeTable("should", + // func(getInput func() bson.M, expected []bson.M, expectError bool) { + // input := getInput() + // _, actual, err := utils.GetDatumUpdates(input) + // if expectError { + // Expect(err).ToNot(BeNil()) + // Expect(actual).To(BeNil()) + // return + // } + // Expect(err).To(BeNil()) + // if expected != nil { + // Expect(actual).To(BeEquivalentTo(expected)) + // } else { + // Expect(actual).To(BeNil()) + // } + // }, + + // Entry("do nothing when not normailzed", + // func() bson.M { + // mmolL := glucose.MmolL + // cbg := newContinuous(&mmolL) + // cbgData := getBSONData(cbg) + // cbgData["_id"] = expectedID + // cbgData["value"] = 9.5 + // return cbgData + // }, + // []bson.M{{"$set": bson.M{ + // "_deduplicator": bson.M{"hash": "lLCOZJMLvNaBx7dMc31bbX4zwSfPvxcUd0Z1uU/YIAs="}, + // }}}, + // false, + // ), + // Entry("update value when normailzed", + // func() bson.M { + // mgdL := glucose.MgdL + // cbg := newContinuous(&mgdL) + // cbgData := getBSONData(cbg) + // cbgData["_id"] = expectedID + // cbgData["value"] = 180 + + // return cbgData + // }, + // []bson.M{{"$set": bson.M{ + // "_deduplicator": bson.M{"hash": "FZtVRkliues5vAt25ZK+WDAqa4Q6tAAe9h2PdKM15Q4="}, + // "value": pointer.FromFloat64(9.99135), + // "units": pointer.FromString(glucose.MmolL), + // }}}, + // false, + // ), + // ) + // }) + // Context("Historic datum", func() { + // It("g5 dexcom", func() { + // actualID, actual, err := utils.GetDatumUpdates(getBSONData(test.CBGDexcomG5MobDatum)) + // Expect(err).To(BeNil()) + // Expect(actual).ToNot(BeNil()) + // Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "TKJurm+/SuA5tarn/nATa7Nw0LXgwGel67lgJihUctM="}}}})) + // Expect(actualID).ToNot(BeEmpty()) + // }) + + // It("carelink medtronic pumpSettings", func() { + // actualID, actual, err := utils.GetDatumUpdates(getBSONData(test.PumpSettingsCarelink)) + // Expect(err).To(BeNil()) + // Expect(actual).ToNot(BeNil()) + // Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "NC17pw1UAaab50iChhQXJ+N9dTi6GduTy9UjsMHolow="}}}})) + // Expect(actualID).ToNot(BeEmpty()) + // }) + + // It("tandem pumpSettings", func() { + // actualID, actual, err := utils.GetDatumUpdates(getBSONData(test.PumpSettingsTandem)) + // Expect(err).To(BeNil()) + // Expect(actual).ToNot(BeNil()) + // Expect(len(actual)).To(Equal(1)) + // Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "bpKLJbi5JfqD7N0WJ1vj0ck03c9EZ3U0H09TCLhdd3k="}}}})) + // Expect(actualID).ToNot(BeEmpty()) + // }) + + // It("omnipod pumpSettings", func() { + // actualID, actual, err := utils.GetDatumUpdates(getBSONData(test.PumpSettingsOmnipod)) + // Expect(err).To(BeNil()) + // Expect(actual).ToNot(BeNil()) + // Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "oH7/6EEgUjRTeafEpm74fVTYMBvMdQ65/rhg0oFoev8="}}}})) + // Expect(actualID).ToNot(BeEmpty()) + // }) + + // }) + // }) }) }) From 329af8ca08ef18abb5fe2d52d43663b48a05fc63 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 13 Feb 2024 13:08:54 +1300 Subject: [PATCH 194/413] filter out inner payload changes --- migrations/20231128_jellyfish_migration/utils/utils.go | 9 ++++++--- .../20231128_jellyfish_migration/utils/utils_test.go | 7 +++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 90256c966d..919d9c2d49 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -181,6 +181,9 @@ func BuildPlatformDatum(id string, objectData map[string]interface{}) (*data.Dat validator.Time("createdTime", parser.Time("createdTime", time.RFC3339Nano)).Exists() validator.Time("modifiedTime", parser.Time("modifiedTime", time.RFC3339Nano)) + //bolus - not used in the platform + validator.String("deliveryContext", parser.String("deliveryContext")) + parser.NotParsed() if err := parser.Error(); err != nil { @@ -217,7 +220,7 @@ func BuildPlatformDatum(id string, objectData map[string]interface{}) (*data.Dat return datum, nil } -func GetDatumChanges(id string, datum interface{}, original map[string]interface{}, log bool) ([]bson.M, error) { +func GetDatumChanges(id string, datum interface{}, original map[string]interface{}, logging bool) ([]bson.M, error) { outgoingJSONData, err := json.Marshal(datum) if err != nil { @@ -270,7 +273,7 @@ func GetDatumChanges(id string, datum interface{}, original map[string]interface return bson.M{path[1]: bson.M{path[2]: val}} } - for _, change := range changelog { + for _, change := range changelog.FilterOut([]string{"payload"}) { switch change.Type { case diff.CREATE, diff.UPDATE: set[change.Path[0]] = getValue(change.Path, change.To) @@ -286,7 +289,7 @@ func GetDatumChanges(id string, datum interface{}, original map[string]interface if len(unset) > 0 { difference = append(difference, bson.M{"$unset": unset}) } - if log { + if logging { logDiff(id, difference) } return difference, nil diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 36d90f89b2..bf73b95133 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -206,6 +206,13 @@ var _ = Describe("back-37", func() { Expect(err).To(BeNil()) Expect(diff).To(Equal([]bson.M{{"$unset": bson.M{"random": ""}}})) }) + + It("no difference when inner payload changes", func() { + datumObject["payload"] = map[string]interface{}{"stuff": true} + diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject, false) + Expect(err).To(BeNil()) + Expect(diff).To(Equal([]bson.M{})) + }) }) // TODO: switch to audit + update From 4915b2ef36e74b4ab026595ae0a2115d76a66470 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 13 Feb 2024 14:22:32 +1300 Subject: [PATCH 195/413] errors per type --- .../jellyfish_migration.go | 3 +- .../utils/migrationUtil.go | 16 ++-- .../utils/utils.go | 84 +++++++++---------- 3 files changed, 54 insertions(+), 49 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 0a8cc926db..b9b0be2e15 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -323,7 +323,8 @@ func (m *Migration) fetchAndProcess() bool { itemID := fmt.Sprintf("%v", item["_id"]) updates, err := utils.ProcessDatum(itemID, item) if err != nil { - m.migrationUtil.OnError(err, itemID, fmt.Sprintf("[type=%v]", item["type"])) + itemType := fmt.Sprintf("%v", item["type"]) + m.migrationUtil.OnError(err, itemID, itemType, fmt.Sprintf("[type=%s]", itemType)) } if !m.config.audit { for _, update := range updates { diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 036ccab9d1..3bde1cc54f 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -59,7 +59,7 @@ type MigrationStats struct { type MigrationUtil interface { Initialize(ctx context.Context, dataC *mongo.Collection) error Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func() bool) error - OnError(reportErr error, id string, msg string) + OnError(reportErr error, datumID string, datumType string, msg string) SetUpdates(update ...*mongo.UpdateOneModel) SetLastProcessed(lastID string) SetFetched(raw []bson.M) @@ -224,11 +224,17 @@ func (c *MigrationUtilConfig) SetStopOnErr(stopOnErr bool) *MigrationUtilConfig // OnError // - write error to file `error.log` in directory cli is running in // - optionally stop the operation if stopOnErr is true in the config -func (m *migrationUtil) OnError(reportErr error, id string, msg string) { +func (m *migrationUtil) OnError(reportErr error, datumID string, datumType string, msg string) { var errFormat = "[_id=%s] %s %s\n" if reportErr != nil { m.errorsCount++ - f, err := os.OpenFile("error.log", + + logName := "error.log" + if datumType != "" { + logName = fmt.Sprintf("error_%s.log", datumType) + } + + f, err := os.OpenFile(logName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { log.Println(err) @@ -241,9 +247,9 @@ func (m *migrationUtil) OnError(reportErr error, id string, msg string) { log.Println(err) os.Exit(1) } - f.WriteString(fmt.Sprintf("[_id=%s] %s %s\n", id, msg, string(errBytes))) + f.WriteString(fmt.Sprintf("[_id=%s] %s %s\n", datumID, msg, string(errBytes))) if m.config.stopOnErr { - log.Printf(errFormat, id, msg, reportErr.Error()) + log.Printf(errFormat, datumID, msg, reportErr.Error()) os.Exit(1) } } diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 919d9c2d49..242254abbc 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -5,7 +5,6 @@ import ( "fmt" "log" "os" - "slices" "strings" "time" @@ -20,7 +19,6 @@ import ( "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" "github.com/tidepool-org/platform/data/types/blood/ketone" "github.com/tidepool-org/platform/data/types/calculator" - "github.com/tidepool-org/platform/data/types/common" dataTypesFactory "github.com/tidepool-org/platform/data/types/factory" "github.com/tidepool-org/platform/data/types/settings/pump" errorsP "github.com/tidepool-org/platform/errors" @@ -29,48 +27,48 @@ import ( structureValidator "github.com/tidepool-org/platform/structure/validator" ) -func updateIfExistsPumpSettingsSleepSchedules(bsonData bson.M) (*pump.SleepScheduleMap, error) { - //TODO: currently an array but should be a map for consistency. On pump is "Sleep Schedule 1", "Sleep Schedule 2" - scheduleNames := map[int]string{0: "1", 1: "2"} +// func updateIfExistsPumpSettingsSleepSchedules(bsonData bson.M) (*pump.SleepScheduleMap, error) { +// //TODO: currently an array but should be a map for consistency. On pump is "Sleep Schedule 1", "Sleep Schedule 2" +// scheduleNames := map[int]string{0: "1", 1: "2"} - if schedules := bsonData["sleepSchedules"]; schedules != nil { - sleepScheduleMap := pump.SleepScheduleMap{} - dataBytes, err := json.Marshal(schedules) - if err != nil { - return nil, err - } - schedulesArray := []*pump.SleepSchedule{} - err = json.Unmarshal(dataBytes, &schedulesArray) - if err != nil { - return nil, err - } - for i, schedule := range schedulesArray { - days := schedule.Days - updatedDays := []string{} - for _, day := range *days { - if !slices.Contains(common.DaysOfWeek(), strings.ToLower(day)) { - return nil, errorsP.Newf("pumpSettings.sleepSchedules has an invalid day of week %s", day) - } - updatedDays = append(updatedDays, strings.ToLower(day)) - } - schedule.Days = &updatedDays - sleepScheduleMap[scheduleNames[i]] = schedule - } - //sorts schedules based on day - sleepScheduleMap.Normalize(dataNormalizer.New()) - return &sleepScheduleMap, nil - } - return nil, nil -} +// if schedules := bsonData["sleepSchedules"]; schedules != nil { +// sleepScheduleMap := pump.SleepScheduleMap{} +// dataBytes, err := json.Marshal(schedules) +// if err != nil { +// return nil, err +// } +// schedulesArray := []*pump.SleepSchedule{} +// err = json.Unmarshal(dataBytes, &schedulesArray) +// if err != nil { +// return nil, err +// } +// for i, schedule := range schedulesArray { +// days := schedule.Days +// updatedDays := []string{} +// for _, day := range *days { +// if !slices.Contains(common.DaysOfWeek(), strings.ToLower(day)) { +// return nil, errorsP.Newf("pumpSettings.sleepSchedules has an invalid day of week %s", day) +// } +// updatedDays = append(updatedDays, strings.ToLower(day)) +// } +// schedule.Days = &updatedDays +// sleepScheduleMap[scheduleNames[i]] = schedule +// } +// //sorts schedules based on day +// sleepScheduleMap.Normalize(dataNormalizer.New()) +// return &sleepScheduleMap, nil +// } +// return nil, nil +// } -func pumpSettingsHasBolus(bsonData bson.M) bool { - if bolus := bsonData["bolus"]; bolus != nil { - if _, ok := bolus.(*pump.BolusMap); ok { - return true - } - } - return false -} +// func pumpSettingsHasBolus(bsonData bson.M) bool { +// if bolus := bsonData["bolus"]; bolus != nil { +// if _, ok := bolus.(*pump.BolusMap); ok { +// return true +// } +// } +// return false +// } func logDiff(id string, updates interface{}) { updatesJSON, _ := json.Marshal(updates) @@ -119,7 +117,7 @@ func ApplyBaseChanges(bsonData bson.M) error { } case calculator.Type: if bolus := bsonData["bolus"]; bolus != nil { - //TODO ignore these ?? + //TODO ignore these, the property is just a pointer to the actual bolus delete(bsonData, "bolus") } } From b41fbdfc61a472ed3233cd771812109e41a0ca95 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 13 Feb 2024 14:44:24 +1300 Subject: [PATCH 196/413] type specific validator changes --- .../jellyfish_migration.go | 4 ++-- .../utils/utils.go | 21 +++++++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index b9b0be2e15..e3ff7a0993 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -321,9 +321,9 @@ func (m *Migration) fetchAndProcess() bool { return false } itemID := fmt.Sprintf("%v", item["_id"]) - updates, err := utils.ProcessDatum(itemID, item) + itemType := fmt.Sprintf("%v", item["type"]) + updates, err := utils.ProcessDatum(itemID, itemType, item) if err != nil { - itemType := fmt.Sprintf("%v", item["type"]) m.migrationUtil.OnError(err, itemID, itemType, fmt.Sprintf("[type=%s]", itemType)) } if !m.config.audit { diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 242254abbc..1debd9ffe7 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -18,6 +18,7 @@ import ( "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" "github.com/tidepool-org/platform/data/types/blood/ketone" + "github.com/tidepool-org/platform/data/types/bolus" "github.com/tidepool-org/platform/data/types/calculator" dataTypesFactory "github.com/tidepool-org/platform/data/types/factory" "github.com/tidepool-org/platform/data/types/settings/pump" @@ -152,7 +153,7 @@ func ApplyBaseChanges(bsonData bson.M) error { return nil } -func BuildPlatformDatum(id string, objectData map[string]interface{}) (*data.Datum, error) { +func BuildPlatformDatum(objID string, objType string, objectData map[string]interface{}) (*data.Datum, error) { parser := structureParser.NewObject(&objectData) validator := structureValidator.New() normalizer := dataNormalizer.New() @@ -162,7 +163,7 @@ func BuildPlatformDatum(id string, objectData map[string]interface{}) (*data.Dat (*datum).Validate(validator) (*datum).Normalize(normalizer) } else { - return nil, errorsP.Newf("no datum returned for id=[%s]", id) + return nil, errorsP.Newf("no datum returned for id=[%s]", objID) } validator.Bool("_active", parser.Bool("_active")).Exists() @@ -179,8 +180,16 @@ func BuildPlatformDatum(id string, objectData map[string]interface{}) (*data.Dat validator.Time("createdTime", parser.Time("createdTime", time.RFC3339Nano)).Exists() validator.Time("modifiedTime", parser.Time("modifiedTime", time.RFC3339Nano)) - //bolus - not used in the platform - validator.String("deliveryContext", parser.String("deliveryContext")) + //parsed but not used in the platform + //deletes will be created from the diff + + switch objType { + case continuous.Type: + validator.String("subType", parser.String("subType")) + validator.String("payload", parser.String("payload")) + case bolus.Type: + validator.String("deliveryContext", parser.String("deliveryContext")) + } parser.NotParsed() @@ -293,7 +302,7 @@ func GetDatumChanges(id string, datum interface{}, original map[string]interface return difference, nil } -func ProcessDatum(dataID string, bsonData bson.M) ([]bson.M, error) { +func ProcessDatum(dataID string, dataType string, bsonData bson.M) ([]bson.M, error) { if err := ApplyBaseChanges(bsonData); err != nil { return nil, err @@ -308,7 +317,7 @@ func ProcessDatum(dataID string, bsonData bson.M) ([]bson.M, error) { return nil, err } - datum, err := BuildPlatformDatum(dataID, ojbData) + datum, err := BuildPlatformDatum(dataID, dataType, ojbData) if err != nil { return nil, err } From f7334c51fb1f16a875dd049b36ec02f3abd41afa Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 13 Feb 2024 14:48:00 +1300 Subject: [PATCH 197/413] fix payload type --- migrations/20231128_jellyfish_migration/utils/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 1debd9ffe7..e81fc77f59 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -186,7 +186,7 @@ func BuildPlatformDatum(objID string, objType string, objectData map[string]inte switch objType { case continuous.Type: validator.String("subType", parser.String("subType")) - validator.String("payload", parser.String("payload")) + validator.Object("payload", parser.Object("payload")) case bolus.Type: validator.String("deliveryContext", parser.String("deliveryContext")) } From 4a0fe93f0f90b1e6ea2a0c55df4e5e7665150dbc Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 13 Feb 2024 15:25:00 +1300 Subject: [PATCH 198/413] parse for specific types --- migrations/20231128_jellyfish_migration/utils/utils.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index e81fc77f59..aba8df60e7 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -20,6 +20,7 @@ import ( "github.com/tidepool-org/platform/data/types/blood/ketone" "github.com/tidepool-org/platform/data/types/bolus" "github.com/tidepool-org/platform/data/types/calculator" + "github.com/tidepool-org/platform/data/types/device" dataTypesFactory "github.com/tidepool-org/platform/data/types/factory" "github.com/tidepool-org/platform/data/types/settings/pump" errorsP "github.com/tidepool-org/platform/errors" @@ -186,9 +187,13 @@ func BuildPlatformDatum(objID string, objType string, objectData map[string]inte switch objType { case continuous.Type: validator.String("subType", parser.String("subType")) - validator.Object("payload", parser.Object("payload")) case bolus.Type: validator.String("deliveryContext", parser.String("deliveryContext")) + case basal.Type: + validator.Object("suppressed", parser.Object("suppressed")) + case device.Type: + validator.Object("previous", parser.Object("previous")) + validator.Int("index", parser.Int("index")) } parser.NotParsed() From 56816a74dd1e2bbac879bfeb24195cd0f5d12d06 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 13 Feb 2024 15:30:50 +1300 Subject: [PATCH 199/413] move percent so it is deleted in update --- migrations/20231128_jellyfish_migration/utils/utils.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index aba8df60e7..77cdc1e615 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -102,7 +102,6 @@ func ApplyBaseChanges(bsonData bson.M) error { floatParts := strings.Split(floatStr, ".") if len(floatParts) == 2 { if len(floatParts[1]) > 5 { - //TODO update in mongo if floatVal, ok := bsonData["value"].(float64); ok { mgdlVal := floatVal * glucose.MmolLToMgdLConversionFactor intValue := int(mgdlVal/glucose.MmolLToMgdLConversionFactor*glucose.MmolLToMgdLPrecisionFactor + 0.5) @@ -112,11 +111,6 @@ func ApplyBaseChanges(bsonData bson.M) error { } } } - case basal.Type: - if percent := bsonData["percent"]; percent != nil { - //TODO delete from mongo - delete(bsonData, "percent") - } case calculator.Type: if bolus := bsonData["bolus"]; bolus != nil { //TODO ignore these, the property is just a pointer to the actual bolus @@ -191,6 +185,7 @@ func BuildPlatformDatum(objID string, objType string, objectData map[string]inte validator.String("deliveryContext", parser.String("deliveryContext")) case basal.Type: validator.Object("suppressed", parser.Object("suppressed")) + validator.Float64("percent", parser.Float64("percent")) case device.Type: validator.Object("previous", parser.Object("previous")) validator.Int("index", parser.Int("index")) From 8912a52ed9156b38bbbbb261560d38a3daf3a07f Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 13 Feb 2024 15:46:13 +1300 Subject: [PATCH 200/413] try to remove empty payload --- .../utils/utils.go | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 77cdc1e615..d59609333a 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -119,17 +119,21 @@ func ApplyBaseChanges(bsonData bson.M) error { } if payload := bsonData["payload"]; payload != nil { - if _, ok := payload.(string); ok { - dataBytes, err := bson.Marshal(payload) - if err != nil { - return err - } - var payloadMetadata metadata.Metadata - err = bson.Unmarshal(dataBytes, &payloadMetadata) - if err != nil { - return errorsP.Newf("payload could not be set from %v ", string(dataBytes)) + if strPayload, ok := payload.(string); ok { + if strPayload == "" { + delete(bsonData, "payload") + } else { + dataBytes, err := bson.Marshal(payload) + if err != nil { + return err + } + var payloadMetadata metadata.Metadata + err = bson.Unmarshal(dataBytes, &payloadMetadata) + if err != nil { + return errorsP.Newf("payload could not be set from %v ", string(dataBytes)) + } + bsonData["payload"] = &payloadMetadata } - bsonData["payload"] = &payloadMetadata } } if annotations := bsonData["annotations"]; annotations != nil { From 204ff7ec019fcdd25f6e1c0d02470f0f7c97ad85 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 13 Feb 2024 16:38:51 +1300 Subject: [PATCH 201/413] remove payload --- migrations/20231128_jellyfish_migration/utils/utils.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index d59609333a..63e1fc21b1 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -135,6 +135,13 @@ func ApplyBaseChanges(bsonData bson.M) error { bsonData["payload"] = &payloadMetadata } } + if dType == continuous.Type { + if metaPayload, ok := payload.(metadata.Metadata); ok { + if len(metaPayload) == 0 { + delete(bsonData, "payload") + } + } + } } if annotations := bsonData["annotations"]; annotations != nil { if _, ok := annotations.(string); ok { From ace65386130b90fc71e9975d06ffc2fd0f0b52b6 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 13 Feb 2024 16:55:36 +1300 Subject: [PATCH 202/413] type specific updates --- .../utils/utils.go | 24 ++++++++++--------- .../utils/utils_test.go | 24 ++++++++++++------- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 63e1fc21b1..e593f00054 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -86,9 +86,9 @@ func logDiff(id string, updates interface{}) { } } -func ApplyBaseChanges(bsonData bson.M) error { - dType := fmt.Sprintf("%v", bsonData["type"]) - switch dType { +func ApplyBaseChanges(bsonData bson.M, dataType string) error { + + switch dataType { case pump.Type: if boluses := bsonData["bolus"]; boluses != nil { bsonData["boluses"] = boluses @@ -111,6 +111,15 @@ func ApplyBaseChanges(bsonData bson.M) error { } } } + if dataType == continuous.Type { + if payload := bsonData["payload"]; payload != nil { + if md, ok := payload.(metadata.Metadata); ok { + if len(md) == 0 { + delete(bsonData, "payload") + } + } + } + } case calculator.Type: if bolus := bsonData["bolus"]; bolus != nil { //TODO ignore these, the property is just a pointer to the actual bolus @@ -135,13 +144,6 @@ func ApplyBaseChanges(bsonData bson.M) error { bsonData["payload"] = &payloadMetadata } } - if dType == continuous.Type { - if metaPayload, ok := payload.(metadata.Metadata); ok { - if len(metaPayload) == 0 { - delete(bsonData, "payload") - } - } - } } if annotations := bsonData["annotations"]; annotations != nil { if _, ok := annotations.(string); ok { @@ -315,7 +317,7 @@ func GetDatumChanges(id string, datum interface{}, original map[string]interface func ProcessDatum(dataID string, dataType string, bsonData bson.M) ([]bson.M, error) { - if err := ApplyBaseChanges(bsonData); err != nil { + if err := ApplyBaseChanges(bsonData, dataType); err != nil { return nil, err } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index bf73b95133..49e521143a 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -56,18 +56,20 @@ var _ = Describe("back-37", func() { "bolus-2": pumpTest.NewRandomBolus(), } var settingsBolusDatum bson.M + var datumType string BeforeEach(func() { settingsBolusDatum = getBSONData(pumpSettingsDatum) settingsBolusDatum["bolus"] = bolusData settingsBolusDatum["_id"] = expectedID + datumType = fmt.Sprintf("%v", settingsBolusDatum["type"]) }) It("should do nothing when has no bolus", func() { settingsBolusDatum["bolus"] = nil Expect(settingsBolusDatum["bolus"]).To(BeNil()) - err := utils.ApplyBaseChanges(settingsBolusDatum) + err := utils.ApplyBaseChanges(settingsBolusDatum, datumType) Expect(err).To(BeNil()) Expect(settingsBolusDatum["bolus"]).To(BeNil()) }) @@ -75,7 +77,7 @@ var _ = Describe("back-37", func() { It("should rename as boluses when bolus found", func() { settingsBolusDatum["bolus"] = nil Expect(settingsBolusDatum["bolus"]).To(BeNil()) - err := utils.ApplyBaseChanges(settingsBolusDatum) + err := utils.ApplyBaseChanges(settingsBolusDatum, datumType) Expect(err).To(BeNil()) Expect(settingsBolusDatum["bolus"]).To(BeNil()) }) @@ -93,6 +95,7 @@ var _ = Describe("back-37", func() { *datum.Time = theTime return datum } + datumType := "cbg" It("should do nothing when value is already correct", func() { mmoll := glucose.MmolL @@ -102,7 +105,7 @@ var _ = Describe("back-37", func() { cbgData["value"] = 4.88466 Expect(cbgData["value"]).To(Equal(4.88466)) - err := utils.ApplyBaseChanges(cbgData) + err := utils.ApplyBaseChanges(cbgData, datumType) Expect(err).To(BeNil()) Expect(cbgData["value"]).To(Equal(4.88466)) }) @@ -114,23 +117,26 @@ var _ = Describe("back-37", func() { cbgData["value"] = 4.88465823212007 Expect(cbgData["value"]).To(Equal(4.88465823212007)) - err := utils.ApplyBaseChanges(cbgData) + err := utils.ApplyBaseChanges(cbgData, datumType) Expect(err).To(BeNil()) Expect(cbgData["value"]).To(Equal(4.88466)) }) }) Context("datum with string payload", func() { var datumWithPayload primitive.M + var datumType string + var payload *metadata.Metadata BeforeEach(func() { datumWithPayload = getBSONData(pumpSettingsDatum) payload = metadataTest.RandomMetadata() datumWithPayload["payload"] = *payload + datumType = fmt.Sprintf("%v", datumWithPayload["type"]) }) It("should do nothing when value is already correct", func() { Expect(datumWithPayload["payload"]).To(Equal(*payload)) - err := utils.ApplyBaseChanges(datumWithPayload) + err := utils.ApplyBaseChanges(datumWithPayload, datumType) Expect(err).To(BeNil()) Expect(datumWithPayload["payload"]).To(Equal(*payload)) }) @@ -138,7 +144,7 @@ var _ = Describe("back-37", func() { Skip("sort out setting as string") datumWithPayload["payload"] = fmt.Sprintf("%v", getBSONData(*payload)) Expect(datumWithPayload["payload"]).To(Equal(fmt.Sprintf("%v", *payload))) - err := utils.ApplyBaseChanges(datumWithPayload) + err := utils.ApplyBaseChanges(datumWithPayload, datumType) Expect(err).To(BeNil()) Expect(datumWithPayload["payload"]).To(Equal(*payload)) }) @@ -146,15 +152,17 @@ var _ = Describe("back-37", func() { Context("datum with string annotations", func() { var datumWithAnnotation primitive.M var annotations *metadata.MetadataArray + var datumType string BeforeEach(func() { datumWithAnnotation = getBSONData(pumpSettingsDatum) annotations = metadataTest.RandomMetadataArray() datumWithAnnotation["annotations"] = *annotations + datumType = fmt.Sprintf("%v", datumWithAnnotation["type"]) }) It("should do nothing when value is already correct", func() { Expect(datumWithAnnotation["annotations"]).To(Equal(*annotations)) - err := utils.ApplyBaseChanges(datumWithAnnotation) + err := utils.ApplyBaseChanges(datumWithAnnotation, datumType) Expect(err).To(BeNil()) Expect(datumWithAnnotation["annotations"]).To(Equal(*annotations)) }) @@ -162,7 +170,7 @@ var _ = Describe("back-37", func() { Skip("sort out setting as string") datumWithAnnotation["annotations"] = fmt.Sprintf("%v", getBSONData(*annotations)) Expect(datumWithAnnotation["annotations"]).To(Equal(fmt.Sprintf("%v", *annotations))) - err := utils.ApplyBaseChanges(datumWithAnnotation) + err := utils.ApplyBaseChanges(datumWithAnnotation, datumType) Expect(err).To(BeNil()) Expect(datumWithAnnotation["annotations"]).To(Equal(*annotations)) }) From 203427e8dd7fc8e37400c7008c8efae7604d9380 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 13 Feb 2024 17:19:42 +1300 Subject: [PATCH 203/413] allow updates --- .../jellyfish_migration.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index e3ff7a0993..aaa77795a7 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -84,13 +84,13 @@ func (m *Migration) RunAndExit() { return err } - if m.config.audit { - log.Println("auditing") - if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndProcess); err != nil { - log.Printf("audit failed: %s", err) - return err - } + //if m.config.audit { + // log.Println("auditing") + if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndProcess); err != nil { + log.Printf("audit failed: %s", err) + return err } + //} // TODO: switch to audit + update // } else { // if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndUpdateBatch); err != nil { From 87a97dfae520ae13b9443e862066602147b067e1 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 13 Feb 2024 18:27:04 +1300 Subject: [PATCH 204/413] log if auditing --- .../jellyfish_migration.go | 13 +------------ .../20231128_jellyfish_migration/utils/utils.go | 4 ++-- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index aaa77795a7..5ddfa45c27 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -83,21 +83,10 @@ func (m *Migration) RunAndExit() { log.Printf("prepare failed: %s", err) return err } - - //if m.config.audit { - // log.Println("auditing") if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndProcess); err != nil { log.Printf("audit failed: %s", err) return err } - //} - // TODO: switch to audit + update - // } else { - // if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndUpdateBatch); err != nil { - // log.Printf("execute failed: %s", err) - // return err - // } - // } return nil } @@ -322,7 +311,7 @@ func (m *Migration) fetchAndProcess() bool { } itemID := fmt.Sprintf("%v", item["_id"]) itemType := fmt.Sprintf("%v", item["type"]) - updates, err := utils.ProcessDatum(itemID, itemType, item) + updates, err := utils.ProcessDatum(itemID, itemType, item, m.config.audit) if err != nil { m.migrationUtil.OnError(err, itemID, itemType, fmt.Sprintf("[type=%s]", itemType)) } diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index e593f00054..3047d044ae 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -315,7 +315,7 @@ func GetDatumChanges(id string, datum interface{}, original map[string]interface return difference, nil } -func ProcessDatum(dataID string, dataType string, bsonData bson.M) ([]bson.M, error) { +func ProcessDatum(dataID string, dataType string, bsonData bson.M, logChanges bool) ([]bson.M, error) { if err := ApplyBaseChanges(bsonData, dataType); err != nil { return nil, err @@ -335,7 +335,7 @@ func ProcessDatum(dataID string, dataType string, bsonData bson.M) ([]bson.M, er return nil, err } - updates, err := GetDatumChanges(dataID, datum, ojbData, true) + updates, err := GetDatumChanges(dataID, datum, ojbData, logChanges) if err != nil { return nil, err } From da9bbe936a1ea9a8a162737c3f2ccb4333f661d9 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 13 Feb 2024 18:58:49 +1300 Subject: [PATCH 205/413] remove needless logging --- .../20231128_jellyfish_migration/utils/migrationUtil.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 3bde1cc54f..8125d4a5a0 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -110,8 +110,8 @@ func (m *migrationUtil) Initialize(ctx context.Context, dataC *mongo.Collection) func (m *migrationUtil) capReached() bool { if m.config.cap != nil { stats := m.GetStats() - log.Printf("cap [%d] updated [%d] fetched [%d]", *m.config.cap, stats.Applied, stats.Fetched) if *m.config.cap <= stats.Applied || *m.config.cap <= stats.Fetched { + log.Printf("cap [%d] updated [%d] fetched [%d]", *m.config.cap, stats.Applied, stats.Fetched) return true } } @@ -144,7 +144,6 @@ func (m *migrationUtil) SetLastProcessed(lastID string) { func (m *migrationUtil) SetFetched(raw []bson.M) { m.rawData = append(m.rawData, raw...) - log.Printf("fetched [%d]", len(m.rawData)) } func (m *migrationUtil) GetStats() MigrationStats { @@ -425,7 +424,6 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio return errors.New("missing required collection to write updates to") } if len(m.updates) == 0 { - log.Println("no updates to apply") return nil } From 5941ddcefe87fa379436d330e9bef63cc1ef34af Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 14 Feb 2024 10:41:55 +1300 Subject: [PATCH 206/413] tests and updates --- .../utils/test/data.go | 2 +- .../utils/utils.go | 74 +++++--- .../utils/utils_test.go | 178 +++++++++++++----- 3 files changed, 182 insertions(+), 72 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go index fa6108e845..128034c071 100644 --- a/migrations/20231128_jellyfish_migration/utils/test/data.go +++ b/migrations/20231128_jellyfish_migration/utils/test/data.go @@ -21,7 +21,7 @@ func base(deviceID string) map[string]interface{} { func dexG5MobDatum() map[string]interface{} { datum := base("DexG5Mob_iPhone") datum["annotations"] = `[{"code":"bg/out-of-range","threshold":40,"value":"low"}]` - datum["payload"] = `{\"systemTime\":\"2017-11-05T18:56:51Z\",\"transmitterId\":\"410X6M\",\"transmitterTicks\":5796922,\"trend\":\"flat\",\"trendRate\":0.6,\"trendRateUnits\":\"mg/dL/min\"}` + datum["payload"] = `{"systemTime":"2017-11-05T18:56:51Z","transmitterId":"410X6M","transmitterTicks":5796922,"trend":"flat","trendRate":0.6,"trendRateUnits":"mg/dL/min"}` datum["type"] = "cbg" datum["units"] = "mmol/L" datum["value"] = 8.1596 diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 3047d044ae..8f08cd654c 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "os" + "slices" "strings" "time" @@ -20,6 +21,7 @@ import ( "github.com/tidepool-org/platform/data/types/blood/ketone" "github.com/tidepool-org/platform/data/types/bolus" "github.com/tidepool-org/platform/data/types/calculator" + "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/data/types/device" dataTypesFactory "github.com/tidepool-org/platform/data/types/factory" "github.com/tidepool-org/platform/data/types/settings/pump" @@ -90,11 +92,39 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { switch dataType { case pump.Type: + //mis-named boluses if boluses := bsonData["bolus"]; boluses != nil { bsonData["boluses"] = boluses //TODO delete from mongo delete(bsonData, "bolus") } + if schedules := bsonData["sleepSchedules"]; schedules != nil { + scheduleNames := map[int]string{0: "1", 1: "2"} + sleepScheduleMap := pump.SleepScheduleMap{} + dataBytes, err := json.Marshal(schedules) + if err != nil { + return err + } + schedulesArray := []*pump.SleepSchedule{} + err = json.Unmarshal(dataBytes, &schedulesArray) + if err != nil { + return err + } + for i, schedule := range schedulesArray { + days := schedule.Days + updatedDays := []string{} + for _, day := range *days { + if !slices.Contains(common.DaysOfWeek(), strings.ToLower(day)) { + return errorsP.Newf("pumpSettings.sleepSchedules has an invalid day of week %s", day) + } + updatedDays = append(updatedDays, strings.ToLower(day)) + } + schedule.Days = &updatedDays + sleepScheduleMap[scheduleNames[i]] = schedule + } + bsonData["sleepSchedules"] = &sleepScheduleMap + } + case selfmonitored.Type, ketone.Type, continuous.Type: units := fmt.Sprintf("%v", bsonData["units"]) if units == glucose.MmolL || units == glucose.Mmoll { @@ -111,15 +141,6 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { } } } - if dataType == continuous.Type { - if payload := bsonData["payload"]; payload != nil { - if md, ok := payload.(metadata.Metadata); ok { - if len(md) == 0 { - delete(bsonData, "payload") - } - } - } - } case calculator.Type: if bolus := bsonData["bolus"]; bolus != nil { //TODO ignore these, the property is just a pointer to the actual bolus @@ -128,32 +149,27 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { } if payload := bsonData["payload"]; payload != nil { - if strPayload, ok := payload.(string); ok { - if strPayload == "" { + + if md, ok := payload.(*metadata.Metadata); ok { + if len(*md) == 0 { delete(bsonData, "payload") - } else { - dataBytes, err := bson.Marshal(payload) - if err != nil { - return err - } - var payloadMetadata metadata.Metadata - err = bson.Unmarshal(dataBytes, &payloadMetadata) - if err != nil { - return errorsP.Newf("payload could not be set from %v ", string(dataBytes)) - } - bsonData["payload"] = &payloadMetadata } } - } - if annotations := bsonData["annotations"]; annotations != nil { - if _, ok := annotations.(string); ok { - dataBytes, err := bson.Marshal(annotations) + + if strPayload, ok := payload.(string); ok { + var payloadMetadata metadata.Metadata + err := json.Unmarshal(json.RawMessage(strPayload), &payloadMetadata) if err != nil { - return err + return errorsP.Newf("payload could not be set from %s", strPayload) } + bsonData["payload"] = &payloadMetadata + } + } + if annotations := bsonData["annotations"]; annotations != nil { + if strAnnotations, ok := annotations.(string); ok { var metadataArray metadata.MetadataArray - if err := bson.Unmarshal(dataBytes, &metadataArray); err != nil { - return errorsP.Newf("annotations could not be set from %v ", string(dataBytes)) + if err := json.Unmarshal(json.RawMessage(strAnnotations), &metadataArray); err != nil { + return errorsP.Newf("annotations could not be set from %s", strAnnotations) } bsonData["annotations"] = &metadataArray } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 49e521143a..68856cd36b 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -3,6 +3,7 @@ package utils_test import ( "encoding/json" "fmt" + "strings" "time" . "github.com/onsi/ginkgo/v2" @@ -13,6 +14,7 @@ import ( "github.com/tidepool-org/platform/data/blood/glucose" "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" glucoseTest "github.com/tidepool-org/platform/data/types/blood/glucose/test" + "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/data/types/settings/pump" pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" @@ -47,42 +49,94 @@ var _ = Describe("back-37", func() { theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") *pumpSettingsDatum.Time = theTime }) + Context("pumpSettings datum with mis-named jellyfish bolus", func() { + var bolusData = &pump.BolusMap{ + "bolus-1": pumpTest.NewRandomBolus(), + "bolus-2": pumpTest.NewRandomBolus(), + } + var settingsBolusDatum bson.M + var datumType string + + BeforeEach(func() { - Context("pumpSettings", func() { + settingsBolusDatum = getBSONData(pumpSettingsDatum) + settingsBolusDatum["bolus"] = bolusData + settingsBolusDatum["_id"] = expectedID + datumType = fmt.Sprintf("%v", settingsBolusDatum["type"]) + }) + + It("should do nothing when has no bolus", func() { + settingsBolusDatum["bolus"] = nil + Expect(settingsBolusDatum["bolus"]).To(BeNil()) + err := utils.ApplyBaseChanges(settingsBolusDatum, datumType) + Expect(err).To(BeNil()) + Expect(settingsBolusDatum["bolus"]).To(BeNil()) + Expect(settingsBolusDatum["boluses"]).To(BeNil()) + }) + + It("should rename as boluses when bolus found", func() { + Expect(settingsBolusDatum["bolus"]).ToNot(BeNil()) + err := utils.ApplyBaseChanges(settingsBolusDatum, datumType) + Expect(err).To(BeNil()) + Expect(settingsBolusDatum["bolus"]).To(BeNil()) + Expect(settingsBolusDatum["boluses"]).ToNot(BeNil()) + Expect(settingsBolusDatum["boluses"]).To(Equal(bolusData)) + }) + }) + Context("pumpSettings datum with unordered sleepSchedules", func() { + expectedSleepSchedulesMap := &pump.SleepScheduleMap{} + var invalidDays *pump.SleepSchedule + var s1Days *pump.SleepSchedule + var s2Days *pump.SleepSchedule + var sleepSchedulesDatum bson.M + var datumType string - Context("with mis-named jellyfish bolus", func() { - var bolusData = &pump.BolusMap{ - "bolus-1": pumpTest.NewRandomBolus(), - "bolus-2": pumpTest.NewRandomBolus(), + BeforeEach(func() { + sleepSchedulesDatum = getBSONData(pumpSettingsDatum) + datumType = fmt.Sprintf("%v", sleepSchedulesDatum["type"]) + s1 := pumpTest.RandomSleepSchedule() + s2 := pumpTest.RandomSleepSchedule() + (*expectedSleepSchedulesMap)["1"] = s1 + (*expectedSleepSchedulesMap)["2"] = s2 + + s1Days = pumpTest.CloneSleepSchedule(s1) + for key, day := range *s1Days.Days { + (*s1Days.Days)[key] = strings.ToUpper(day) + } + s2Days = pumpTest.CloneSleepSchedule(s2) + for key, day := range *s2Days.Days { + (*s2Days.Days)[key] = strings.ToUpper(day) } - var settingsBolusDatum bson.M - var datumType string - - BeforeEach(func() { - - settingsBolusDatum = getBSONData(pumpSettingsDatum) - settingsBolusDatum["bolus"] = bolusData - settingsBolusDatum["_id"] = expectedID - datumType = fmt.Sprintf("%v", settingsBolusDatum["type"]) - }) - - It("should do nothing when has no bolus", func() { - settingsBolusDatum["bolus"] = nil - Expect(settingsBolusDatum["bolus"]).To(BeNil()) - err := utils.ApplyBaseChanges(settingsBolusDatum, datumType) - Expect(err).To(BeNil()) - Expect(settingsBolusDatum["bolus"]).To(BeNil()) - }) - - It("should rename as boluses when bolus found", func() { - settingsBolusDatum["bolus"] = nil - Expect(settingsBolusDatum["bolus"]).To(BeNil()) - err := utils.ApplyBaseChanges(settingsBolusDatum, datumType) - Expect(err).To(BeNil()) - Expect(settingsBolusDatum["bolus"]).To(BeNil()) - }) + invalidDays = pumpTest.CloneSleepSchedule(s2) + invalidDays.Days = &[]string{"not-a-day", common.DayFriday} + Expect(expectedSleepSchedulesMap).ToNot(BeNil()) + pumpSettingsDatum.SleepSchedules = nil + sleepSchedulesDatum = getBSONData(pumpSettingsDatum) + sleepSchedulesDatum["_id"] = expectedID + sleepSchedulesDatum["bolus"] = nil //remove as not testing here + }) + + It("does nothing when no sleepSchedules", func() { + sleepSchedulesDatum["sleepSchedules"] = nil + err := utils.ApplyBaseChanges(sleepSchedulesDatum, datumType) + Expect(err).To(BeNil()) + Expect(sleepSchedulesDatum["sleepSchedules"]).To(BeNil()) + }) + It("returns updated sleepSchedules when valid", func() { + sleepSchedulesDatum["sleepSchedules"] = []*pump.SleepSchedule{s1Days, s2Days} + err := utils.ApplyBaseChanges(sleepSchedulesDatum, datumType) + Expect(err).To(BeNil()) + Expect(sleepSchedulesDatum["sleepSchedules"]).ToNot(BeNil()) + Expect(sleepSchedulesDatum["sleepSchedules"]).To(Equal(expectedSleepSchedulesMap)) + }) + It("returns error when sleepSchedules have invalid days", func() { + sleepSchedulesDatum["sleepSchedules"] = []*pump.SleepSchedule{invalidDays} + err := utils.ApplyBaseChanges(sleepSchedulesDatum, datumType) + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(Equal("pumpSettings.sleepSchedules has an invalid day of week not-a-day")) }) }) + Context("datum with glucose", func() { var newContinuous = func(units *string) *continuous.Continuous { datum := continuous.New() @@ -96,7 +150,6 @@ var _ = Describe("back-37", func() { return datum } datumType := "cbg" - It("should do nothing when value is already correct", func() { mmoll := glucose.MmolL cbg := newContinuous(&mmoll) @@ -125,7 +178,6 @@ var _ = Describe("back-37", func() { Context("datum with string payload", func() { var datumWithPayload primitive.M var datumType string - var payload *metadata.Metadata BeforeEach(func() { datumWithPayload = getBSONData(pumpSettingsDatum) @@ -141,12 +193,20 @@ var _ = Describe("back-37", func() { Expect(datumWithPayload["payload"]).To(Equal(*payload)) }) It("should update the payload when it is a string", func() { - Skip("sort out setting as string") - datumWithPayload["payload"] = fmt.Sprintf("%v", getBSONData(*payload)) - Expect(datumWithPayload["payload"]).To(Equal(fmt.Sprintf("%v", *payload))) + datumWithPayload["payload"] = `{"transmitterId":"410X6M","transmitterTicks":5796922,"trend":"flat"}` err := utils.ApplyBaseChanges(datumWithPayload, datumType) Expect(err).To(BeNil()) - Expect(datumWithPayload["payload"]).To(Equal(*payload)) + Expect(datumWithPayload["payload"]).To(Equal(&metadata.Metadata{ + "transmitterId": "410X6M", + "transmitterTicks": float64(5796922), + "trend": "flat", + })) + }) + It("should remove the payload when it is empty", func() { + datumWithPayload["payload"] = &metadata.Metadata{} + err := utils.ApplyBaseChanges(datumWithPayload, datumType) + Expect(err).To(BeNil()) + Expect(datumWithPayload["payload"]).To(BeNil()) }) }) Context("datum with string annotations", func() { @@ -167,13 +227,47 @@ var _ = Describe("back-37", func() { Expect(datumWithAnnotation["annotations"]).To(Equal(*annotations)) }) It("should update the annotations when it is a string", func() { - Skip("sort out setting as string") - datumWithAnnotation["annotations"] = fmt.Sprintf("%v", getBSONData(*annotations)) - Expect(datumWithAnnotation["annotations"]).To(Equal(fmt.Sprintf("%v", *annotations))) + datumWithAnnotation["annotations"] = `[{"code":"bg/out-of-range","threshold":40,"value":"low"}]` + err := utils.ApplyBaseChanges(datumWithAnnotation, datumType) + Expect(err).To(BeNil()) + Expect(datumWithAnnotation["annotations"]).To(Equal(&metadata.MetadataArray{ + &metadata.Metadata{ + "code": "bg/out-of-range", + "threshold": float64(40), + "value": "low", + }, + })) + }) + }) + Context("datum with string annotations", func() { + var datumWithAnnotation primitive.M + var annotations *metadata.MetadataArray + var datumType string + BeforeEach(func() { + datumWithAnnotation = getBSONData(pumpSettingsDatum) + annotations = metadataTest.RandomMetadataArray() + datumWithAnnotation["annotations"] = *annotations + datumType = fmt.Sprintf("%v", datumWithAnnotation["type"]) + }) + + It("should do nothing when value is already correct", func() { + Expect(datumWithAnnotation["annotations"]).To(Equal(*annotations)) err := utils.ApplyBaseChanges(datumWithAnnotation, datumType) Expect(err).To(BeNil()) Expect(datumWithAnnotation["annotations"]).To(Equal(*annotations)) }) + It("should update the annotations when it is a string", func() { + datumWithAnnotation["annotations"] = `[{"code":"bg/out-of-range","threshold":40,"value":"low"}]` + err := utils.ApplyBaseChanges(datumWithAnnotation, datumType) + Expect(err).To(BeNil()) + Expect(datumWithAnnotation["annotations"]).To(Equal(&metadata.MetadataArray{ + &metadata.Metadata{ + "code": "bg/out-of-range", + "threshold": float64(40), + "value": "low", + }, + })) + }) }) }) @@ -527,7 +621,7 @@ var _ = Describe("back-37", func() { // Expect(actualID).ToNot(BeEmpty()) // }) - // }) - // }) + // }) + // }) }) }) From fb540b95d643498c9d2f24c35140762d7d6d21b2 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 14 Feb 2024 11:12:47 +1300 Subject: [PATCH 207/413] trying to sort empty payload --- .../20231128_jellyfish_migration/tst.json | 1984 +++++++++++++++++ .../utils/utils.go | 10 +- .../utils/utils_test.go | 2 - 3 files changed, 1992 insertions(+), 4 deletions(-) create mode 100644 migrations/20231128_jellyfish_migration/tst.json diff --git a/migrations/20231128_jellyfish_migration/tst.json b/migrations/20231128_jellyfish_migration/tst.json new file mode 100644 index 0000000000..97592ea631 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/tst.json @@ -0,0 +1,1984 @@ +[ + { + "_id": "003pv66tbv4ts0d7dtg87iqgfue2njko", + "diff": [ + { + "$set": { + "bgTarget": { "0": { "low": 0.24649 } }, + "insulinSensitivity": { "3": { "amount": 0.10784 } }, + "units": { "bg": "mmol/L" } + } + } + ] + }, + { + "_id": "003q3akh725mgom2o0veto788r3omfl1", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "004em6c9cjnblofd4mo2kcqg9tlsamec", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "004em6c9cjnblofd4mo2kcqg9tlsamec_0", + "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] + }, + { + "_id": "004mpfpguo8imiijdd72i6ik7d375rq9", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00555ome25877chsjcpfecenmven56ir", + "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] + }, + { + "_id": "0056goqpstl5blnvu4j5ruthmh0ve8lm", + "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] + }, + { + "_id": "0056goqpstl5blnvu4j5ruthmh0ve8lm_0", + "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] + }, + { + "_id": "005hc13gfoq5fv6daph9is1qi5p2qfin", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "005hc13gfoq5fv6daph9is1qi5p2qfin_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00668njtmootganjsu2ulhas9q76npr8", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "006nc3tg0affjbpp9epn2e7oujsl2eoq", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "006nc3tg0affjbpp9epn2e7oujsl2eoq_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "007eslnt672r7irnnp5ri517n64kb0o0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "007eslnt672r7irnnp5ri517n64kb0o0_0", + "diff": [{ "$unset": { "suppressed": { "clockDriftOffset": "" } } }] + }, + { + "_id": "008fps2ork9n3731otmh7m25rjb125ds", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "008fps2ork9n3731otmh7m25rjb125ds_0", + "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] + }, + { + "_id": "008gh26sbih90urq5pgrv6qslhfssqeb", + "diff": [ + { "$unset": { "suppressed": { "suppressed": { "timezoneOffset": "" } } } } + ] + }, + { + "_id": "008gh26sbih90urq5pgrv6qslhfssqeb_0", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "008up7g8cfoid7seogp30dod11clotne", + "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] + }, + { + "_id": "008up7g8cfoid7seogp30dod11clotne_0", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "0090h2apbmd9sc17i3ahl0tdtomadkf8", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "0090h2apbmd9sc17i3ahl0tdtomadkf8_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00941bse1rusk3oir9m2c3gg5i51m9eo", + "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] + }, + { + "_id": "00941bse1rusk3oir9m2c3gg5i51m9eo_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "009fbg2kclihtpfj08mhu9ubdro0fj9d", + "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] + }, + { + "_id": "009fbg2kclihtpfj08mhu9ubdro0fj9d_0", + "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] + }, + { + "_id": "00a7rvhhn17u23hogcob4cu0bfr2mbnk", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "00a7rvhhn17u23hogcob4cu0bfr2mbnk_0", + "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] + }, + { + "_id": "00a9egu2esitblp23n4alk92re21hqad", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "00a9egu2esitblp23n4alk92re21hqad_0", + "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] + }, + { + "_id": "00ak731q2gbn6m436dmu6e78u80jm5v9", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00amphcpherhqco8erolvoj5uf07od4a", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00amphcpherhqco8erolvoj5uf07od4a_0", + "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] + }, + { + "_id": "00banp948lntevb74c9mnus6qoqutgsl", + "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] + }, + { + "_id": "00banp948lntevb74c9mnus6qoqutgsl_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00bhgfrumqssh38i8pia3ti30gfgctcs", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00bnlg7mbpfjvmg4orvdd3783g11s88a", + "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] + }, + { + "_id": "00bnlg7mbpfjvmg4orvdd3783g11s88a_0", + "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] + }, + { + "_id": "00bsjoiu7elkq7tahcspl1apl86f4tql", + "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] + }, + { + "_id": "00bsjoiu7elkq7tahcspl1apl86f4tql_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00c8hsa1d72ns99uv496bsr1lb337n83", + "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] + }, + { + "_id": "00c8hsa1d72ns99uv496bsr1lb337n83_0", + "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] + }, + { + "_id": "00c8jq6crun5762qsl0t5hfkau42utib", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00dcc5rrpur7ppahjrdpse04t66c6ou6", + "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] + }, + { + "_id": "00dcc5rrpur7ppahjrdpse04t66c6ou6_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00ddv5fr5q4hg33253rvd9ajoa4cmtqd", + "diff": [{ "$unset": { "suppressed": { "source": "" } } }] + }, + { + "_id": "00ddv5fr5q4hg33253rvd9ajoa4cmtqd_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00e2eeq17vn9bmsftk3ls7b3t6aibpch", + "diff": [{ "$unset": { "suppressed": { "index": "" } } }] + }, + { + "_id": "00e2eeq17vn9bmsftk3ls7b3t6aibpch_0", + "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] + }, + { + "_id": "00ef5rntkfhr4vql89cvbjkul7qeffv6", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00ekb6v217ugr0ohcsi0qhfq3roq56p1", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00fcpm9tbv1lgmpo7sjehk55v222f1ln", + "diff": [ + { + "$set": { + "rateOfChangeAlert": { + "fallRate": { "enabled": false, "rate": -0.16652243973136602 }, + "riseRate": { "enabled": false, "rate": 0.16652243973136602 } + } + } + }, + { "$unset": { "rateOfChangeAlerts": "" } } + ] + }, + { + "_id": "00fdte897t1h2a8kehh54lh0kui1rsku", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00fopd2svgrq295hg8hjbc5g1640mr2e", + "diff": [ + { + "$set": { + "rateOfChangeAlert": { + "fallRate": { "enabled": true, "rate": -0.16652243973136602 }, + "riseRate": { "enabled": false, "rate": 0.16652243973136602 } + } + } + }, + { "$unset": { "rateOfChangeAlerts": "" } } + ] + }, + { + "_id": "00fshp28i8i1rsfmmvghtb3esoco1pov", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00ftthnoc3m08bjd7f5nuthbktkg119d", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00gri8pvjp8a04erp9agtf9cisb632c2", + "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] + }, + { + "_id": "00gri8pvjp8a04erp9agtf9cisb632c2_0", + "diff": [{ "$unset": { "suppressed": { "clockDriftOffset": "" } } }] + }, + { + "_id": "00h97gipch5r5vek1pb40i9uljrb01ua", + "diff": [ + { + "$set": { + "bgTargets": { "Test1": { "15": 0.36973 } }, + "insulinSensitivities": { "Test1": { "15": 0.33892 } }, + "units": { "bg": "mmol/L" } + } + } + ] + }, + { + "_id": "00hl61lmuje16gko3rvdfdr0sp4qs6ol", + "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] + }, + { + "_id": "00hl61lmuje16gko3rvdfdr0sp4qs6ol_0", + "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] + }, + { + "_id": "00hqa1a9c3cpdcch5d6h7vcos6krh0ce", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00ht555qvki7cbk674v6cm26h2312j61", + "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] + }, + { + "_id": "00ht555qvki7cbk674v6cm26h2312j61_0", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "00i2mohjo2mo2s2kom6hnqrb4f64jshr", + "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] + }, + { + "_id": "00i2mohjo2mo2s2kom6hnqrb4f64jshr_0", + "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] + }, + { + "_id": "00iqofhuol103ba49jalb4h82djkk0o0", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00j6nvem3qr8b67olqv3ii9801t0astn", + "diff": [{ "$unset": { "suppressed": { "source": "" } } }] + }, + { + "_id": "00j6nvem3qr8b67olqv3ii9801t0astn_0", + "diff": [{ "$unset": { "suppressed": { "index": "" } } }] + }, + { + "_id": "00j9eo5f5nh3ien4h4u8ovlrdu46c95n", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "00j9eo5f5nh3ien4h4u8ovlrdu46c95n_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00j9rqcumsqq2sg8832dveg3ido6k0cb", + "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] + }, + { + "_id": "00j9rqcumsqq2sg8832dveg3ido6k0cb_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00jtrn77rnvip9fk855pm8v793esshe8", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00k0vhhfv20b9id8iamhvhcldm7nmg5e", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00krmkvdi13ioii2s4j06jkjq3snos2i", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00ld99qpavd0q36seo86s5clp11jeavd", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00ld99qpavd0q36seo86s5clp11jeavd_0", + "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] + }, + { + "_id": "00m3d1b7m7f72oj4e2p09qtverpui4be", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00mfmt0kohnisnb3giudr05uik0egqmm", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00mfmt0kohnisnb3giudr05uik0egqmm_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00ms1frj45tg7o61a3u84qcpr9nhtmvs", + "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] + }, + { + "_id": "00ms1frj45tg7o61a3u84qcpr9nhtmvs_0", + "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] + }, + { + "_id": "00mvdtkn892cqissvttno8k55t2d0sj5", + "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] + }, + { + "_id": "00n9aks33iug7ri7h2dimh495ub85e74", + "diff": [{ "$unset": { "suppressed": { "clockDriftOffset": "" } } }] + }, + { + "_id": "00n9aks33iug7ri7h2dimh495ub85e74_0", + "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] + }, + { + "_id": "00nqj9ckkvach91pj4e3krsc6ea2guk9", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00obfp50c3kog4kq28ln4ea9tc2pkf7t", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "00obfp50c3kog4kq28ln4ea9tc2pkf7t_0", + "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] + }, + { + "_id": "00oufbhdambbqdlavk39maf4i227hbf8", + "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] + }, + { + "_id": "00oufbhdambbqdlavk39maf4i227hbf8_0", + "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] + }, + { + "_id": "00p3v8dr9qlscvopuhvgk96g7ab6nmd8", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00p3v8dr9qlscvopuhvgk96g7ab6nmd8_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "003pv66tbv4ts0d7dtg87iqgfue2njko", + "diff": [ + { + "$set": { + "bgTarget": { "0": { "low": 0.24649 } }, + "insulinSensitivity": { "3": { "amount": 0.10784 } }, + "units": { "bg": "mmol/L" } + } + } + ] + }, + { + "_id": "003q3akh725mgom2o0veto788r3omfl1", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "004em6c9cjnblofd4mo2kcqg9tlsamec", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "004em6c9cjnblofd4mo2kcqg9tlsamec_0", + "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] + }, + { + "_id": "004mpfpguo8imiijdd72i6ik7d375rq9", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00555ome25877chsjcpfecenmven56ir", + "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] + }, + { + "_id": "0056goqpstl5blnvu4j5ruthmh0ve8lm", + "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] + }, + { + "_id": "0056goqpstl5blnvu4j5ruthmh0ve8lm_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "005hc13gfoq5fv6daph9is1qi5p2qfin", + "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] + }, + { + "_id": "005hc13gfoq5fv6daph9is1qi5p2qfin_0", + "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] + }, + { + "_id": "00668njtmootganjsu2ulhas9q76npr8", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "006nc3tg0affjbpp9epn2e7oujsl2eoq", + "diff": [{ "$unset": { "suppressed": { "clockDriftOffset": "" } } }] + }, + { + "_id": "006nc3tg0affjbpp9epn2e7oujsl2eoq_0", + "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] + }, + { + "_id": "007eslnt672r7irnnp5ri517n64kb0o0", + "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] + }, + { + "_id": "007eslnt672r7irnnp5ri517n64kb0o0_0", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "008fps2ork9n3731otmh7m25rjb125ds", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "008fps2ork9n3731otmh7m25rjb125ds_0", + "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] + }, + { + "_id": "008gh26sbih90urq5pgrv6qslhfssqeb", + "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] + }, + { + "_id": "008gh26sbih90urq5pgrv6qslhfssqeb_0", + "diff": [{ "$unset": { "suppressed": { "source": "" } } }] + }, + { + "_id": "008up7g8cfoid7seogp30dod11clotne", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "008up7g8cfoid7seogp30dod11clotne_0", + "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] + }, + { + "_id": "0090h2apbmd9sc17i3ahl0tdtomadkf8", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "0090h2apbmd9sc17i3ahl0tdtomadkf8_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00941bse1rusk3oir9m2c3gg5i51m9eo", + "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] + }, + { + "_id": "00941bse1rusk3oir9m2c3gg5i51m9eo_0", + "diff": [{ "$unset": { "suppressed": { "clockDriftOffset": "" } } }] + }, + { + "_id": "009fbg2kclihtpfj08mhu9ubdro0fj9d", + "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] + }, + { + "_id": "009fbg2kclihtpfj08mhu9ubdro0fj9d_0", + "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] + }, + { + "_id": "00a7rvhhn17u23hogcob4cu0bfr2mbnk", + "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] + }, + { + "_id": "00a7rvhhn17u23hogcob4cu0bfr2mbnk_0", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "00a9egu2esitblp23n4alk92re21hqad", + "diff": [{ "$unset": { "suppressed": { "index": "" } } }] + }, + { + "_id": "00a9egu2esitblp23n4alk92re21hqad_0", + "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] + }, + { + "_id": "00ak731q2gbn6m436dmu6e78u80jm5v9", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00amphcpherhqco8erolvoj5uf07od4a", + "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] + }, + { + "_id": "00amphcpherhqco8erolvoj5uf07od4a_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00banp948lntevb74c9mnus6qoqutgsl", + "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] + }, + { + "_id": "00banp948lntevb74c9mnus6qoqutgsl_0", + "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] + }, + { + "_id": "00bhgfrumqssh38i8pia3ti30gfgctcs", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00bnlg7mbpfjvmg4orvdd3783g11s88a", + "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] + }, + { + "_id": "00bnlg7mbpfjvmg4orvdd3783g11s88a_0", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "00bsjoiu7elkq7tahcspl1apl86f4tql", + "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] + }, + { + "_id": "00bsjoiu7elkq7tahcspl1apl86f4tql_0", + "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] + }, + { + "_id": "00c8hsa1d72ns99uv496bsr1lb337n83", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "00c8hsa1d72ns99uv496bsr1lb337n83_0", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "00c8jq6crun5762qsl0t5hfkau42utib", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00dcc5rrpur7ppahjrdpse04t66c6ou6", + "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] + }, + { + "_id": "00dcc5rrpur7ppahjrdpse04t66c6ou6_0", + "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] + }, + { + "_id": "00ddv5fr5q4hg33253rvd9ajoa4cmtqd", + "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] + }, + { + "_id": "00ddv5fr5q4hg33253rvd9ajoa4cmtqd_0", + "diff": [{ "$unset": { "suppressed": { "clockDriftOffset": "" } } }] + }, + { + "_id": "00e2eeq17vn9bmsftk3ls7b3t6aibpch", + "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] + }, + { + "_id": "00e2eeq17vn9bmsftk3ls7b3t6aibpch_0", + "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] + }, + { + "_id": "00ef5rntkfhr4vql89cvbjkul7qeffv6", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00ekb6v217ugr0ohcsi0qhfq3roq56p1", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00fcpm9tbv1lgmpo7sjehk55v222f1ln", + "diff": [ + { + "$set": { + "rateOfChangeAlert": { + "fallRate": { "enabled": false, "rate": -0.16652243973136602 }, + "riseRate": { "enabled": false, "rate": 0.16652243973136602 } + } + } + }, + { "$unset": { "rateOfChangeAlerts": "" } } + ] + }, + { + "_id": "00fdte897t1h2a8kehh54lh0kui1rsku", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00fopd2svgrq295hg8hjbc5g1640mr2e", + "diff": [ + { + "$set": { + "rateOfChangeAlert": { + "fallRate": { "enabled": true, "rate": -0.16652243973136602 }, + "riseRate": { "enabled": false, "rate": 0.16652243973136602 } + } + } + }, + { "$unset": { "rateOfChangeAlerts": "" } } + ] + }, + { + "_id": "00fshp28i8i1rsfmmvghtb3esoco1pov", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00ftthnoc3m08bjd7f5nuthbktkg119d", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00gri8pvjp8a04erp9agtf9cisb632c2", + "diff": [{ "$unset": { "suppressed": { "source": "" } } }] + }, + { + "_id": "00gri8pvjp8a04erp9agtf9cisb632c2_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00h97gipch5r5vek1pb40i9uljrb01ua", + "diff": [ + { + "$set": { + "bgTargets": { "Test": { "14": 0.2773 } }, + "insulinSensitivities": { "Test1": { "15": 0.33892 } }, + "units": { "bg": "mmol/L" } + } + } + ] + }, + { + "_id": "00hl61lmuje16gko3rvdfdr0sp4qs6ol", + "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] + }, + { + "_id": "00hl61lmuje16gko3rvdfdr0sp4qs6ol_0", + "diff": [{ "$unset": { "suppressed": { "source": "" } } }] + }, + { + "_id": "00hqa1a9c3cpdcch5d6h7vcos6krh0ce", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00ht555qvki7cbk674v6cm26h2312j61", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00ht555qvki7cbk674v6cm26h2312j61_0", + "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] + }, + { + "_id": "00i2mohjo2mo2s2kom6hnqrb4f64jshr", + "diff": [{ "$unset": { "suppressed": { "index": "" } } }] + }, + { + "_id": "00i2mohjo2mo2s2kom6hnqrb4f64jshr_0", + "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] + }, + { + "_id": "00iqofhuol103ba49jalb4h82djkk0o0", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00j6nvem3qr8b67olqv3ii9801t0astn", + "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] + }, + { + "_id": "00j6nvem3qr8b67olqv3ii9801t0astn_0", + "diff": [{ "$unset": { "suppressed": { "source": "" } } }] + }, + { + "_id": "00j9eo5f5nh3ien4h4u8ovlrdu46c95n", + "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] + }, + { + "_id": "00j9eo5f5nh3ien4h4u8ovlrdu46c95n_0", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "00j9rqcumsqq2sg8832dveg3ido6k0cb", + "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] + }, + { + "_id": "00j9rqcumsqq2sg8832dveg3ido6k0cb_0", + "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] + }, + { + "_id": "00jtrn77rnvip9fk855pm8v793esshe8", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00k0vhhfv20b9id8iamhvhcldm7nmg5e", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00krmkvdi13ioii2s4j06jkjq3snos2i", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00ld99qpavd0q36seo86s5clp11jeavd", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "00ld99qpavd0q36seo86s5clp11jeavd_0", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "00m3d1b7m7f72oj4e2p09qtverpui4be", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00mfmt0kohnisnb3giudr05uik0egqmm", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00mfmt0kohnisnb3giudr05uik0egqmm_0", + "diff": [{ "$unset": { "suppressed": { "source": "" } } }] + }, + { + "_id": "00ms1frj45tg7o61a3u84qcpr9nhtmvs", + "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] + }, + { + "_id": "00ms1frj45tg7o61a3u84qcpr9nhtmvs_0", + "diff": [{ "$unset": { "suppressed": { "clockDriftOffset": "" } } }] + }, + { + "_id": "00mvdtkn892cqissvttno8k55t2d0sj5", + "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] + }, + { + "_id": "00n9aks33iug7ri7h2dimh495ub85e74", + "diff": [{ "$unset": { "suppressed": { "index": "" } } }] + }, + { + "_id": "00n9aks33iug7ri7h2dimh495ub85e74_0", + "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] + }, + { + "_id": "00nqj9ckkvach91pj4e3krsc6ea2guk9", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00obfp50c3kog4kq28ln4ea9tc2pkf7t", + "diff": [{ "$unset": { "suppressed": { "source": "" } } }] + }, + { + "_id": "00obfp50c3kog4kq28ln4ea9tc2pkf7t_0", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "00oufbhdambbqdlavk39maf4i227hbf8", + "diff": [{ "$unset": { "suppressed": { "source": "" } } }] + }, + { + "_id": "00oufbhdambbqdlavk39maf4i227hbf8_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00p3v8dr9qlscvopuhvgk96g7ab6nmd8", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00p3v8dr9qlscvopuhvgk96g7ab6nmd8_0", + "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] + }, + { + "_id": "003pv66tbv4ts0d7dtg87iqgfue2njko", + "diff": [ + { + "$set": { + "bgTarget": { "0": { "low": 0.24649 } }, + "insulinSensitivity": { "3": { "amount": 0.10784 } }, + "units": { "bg": "mmol/L" } + } + } + ] + }, + { + "_id": "003q3akh725mgom2o0veto788r3omfl1", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "003ra7lle4afbui5b8u3jidrs185toua", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "003tcon8tounj2qm8k1v9h5l6pbjqa3b", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "003tosu2cr1vktgaepkromj2i97ld4jk", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0040ubuoala10qr24oa9mvifpb4fl4hr", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0043bmh3l05iumq933vfc5593jg4cv9j", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0043el25dr30hrh0jr5dscnntp20ls60", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0043ql9fkrvkkoipudv8ajforvta9cbn", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00445uh1pj66f3leubc9r5sv09gdd49a", + "diff": [{ "$unset": { "subType": "" } }] + }, + { + "_id": "00466bjjo66c5tkjj2h0q8qgqqosd1jh", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0048m6q2vli52njdm708mhtm775acbuq", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004anqm480clp5a9o3e1rf48jkuqlomn", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004ci48809baufo99uljbdahjup558r4", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004em6c9cjnblofd4mo2kcqg9tlsamec", + "diff": [{ "$unset": { "suppressed": { "source": "" } } }] + }, + { + "_id": "004em6c9cjnblofd4mo2kcqg9tlsamec_0", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "004kh7k5t42k4ci06cmo9dkdnjfo6d9j", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004mpfpguo8imiijdd72i6ik7d375rq9", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "004or2n1c0e7l2qip119t0h3gtt1gpt8", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004pe2e6mjd0je3c6hulhbtm4ql1u0nu", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004pt4qies4j1fn3vjei18p9pkauadlu", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004qs07ruhovdab3af26eko42o4repp5", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004t10h76l4m7f1sdc08i8grb2tl3rt1", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004u2t4kvug6jm31h2pkauh5cg3ud1eb", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004u5jq5tvpd4doci5r5o14brel7u0h8", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004vh9omub24akemqvl2qoiosohk02ig", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00555ome25877chsjcpfecenmven56ir", + "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] + }, + { + "_id": "0056goqpstl5blnvu4j5ruthmh0ve8lm", + "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] + }, + { + "_id": "0056goqpstl5blnvu4j5ruthmh0ve8lm_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "005ce26eb8enbqki8s26lfcrese0eji0", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005d7s5s4isuv35jkqibknsodes9ee0q", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005f1u9eq431t3pecccs8n5u99p37pln", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005fc44ql8u7a9ol6f8tdu3s080dqhtp", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005ggbg3ov1odn9li2g58lkrbn3n4v5m", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005hc13gfoq5fv6daph9is1qi5p2qfin", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "005hc13gfoq5fv6daph9is1qi5p2qfin_0", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "005hj9ua01t6gohbejpg5933j8f1k95t", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005iuclbuba3mtfablgbep4967eoous1", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005jkgj5ckra1up98nolt2c5aaf84c89", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005l02s5mdlgrjegbpajcfqaps58kmqc", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005ljq54s0dqggh2u34oc3dmgej6eqp9", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005ner9db6rau554pr5hkaf56vpphpc5", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005pl16rcd4j8n67v2qg360289jtr0f9", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005ruorcd7r67ura02li9kub84gde52v", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005utsujnbab9ajinah7qp8m70gbondn", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00604qao66ec2sh9p922ua0lv6mfihmp", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0060tke9cuqbcdr2iijsvf82hp9o9v4j", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0062cmrelkeicsrl2lgifqsarqi6b7sb", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0062qd8meqaglivgc4eedpcr10momkdv", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0064vp6s8non1lbkpin8k4kg58dohban", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00668njtmootganjsu2ulhas9q76npr8", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "0067bk24kethveo4jtoiihvdg29kcg90", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0068hksr5t845221jsnrbsm3b5m0qkgo", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0068j9nvdm9h17rb9vghca4j6ucto1ih", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0068mqnq491slqks11nr69sf4a56l9i8", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "006ddgmmnndmsi0itrmjr9q2kd5aad4e", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "006dj5poqljkjqe70mbaua37hmt51uq1", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "006e4nullfmotjd1hh88hh5ji6pmcpru", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "006efkgs0hd157dsgjsq9ogm4o6d4559", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "006f1k73pnc936ljspcrap57v1v0lgf3", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "006fi3c3r07ecqj1vd4gj5q9ohaus4qa", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "006j49e1rt77r7j4v740tjhskqfvimkd", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "006l3kga1ckaada9b5asekpkf6bi6nq9", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "006l3rotk6jmtm50ociedbbg9201n8os", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "006l6ckiloj3c705krg64qu6fi9avdi2", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "006nc3tg0affjbpp9epn2e7oujsl2eoq", + "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] + }, + { + "_id": "006nc3tg0affjbpp9epn2e7oujsl2eoq_0", + "diff": [{ "$unset": { "suppressed": { "source": "" } } }] + }, + { + "_id": "006o8hvfctons14ei4gkjrj4auth84hc", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "006oio2dok49d6pg5q0c8tautr0c9fn7", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "006oouq2bu3rugdq3laa5c89639u0io4", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "006otlt26p25f9qp9ehogglcd0ed9l62", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "006v149utv948n22ium7m5p1cr6hha73", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "006vihufp0tb10g9gla20qbrf2edku9l", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0073t0edlm57btvbujtgg41n5u1bjssl", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0074fglsh754iumf7gojg583h6ojmhk5", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0075cs940t81r78prn37evn3ae0v3se5", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0077ksousf8nfon712op5ep1gt27oka9", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0078ggolc99q04nc6pu0ladf6s42bn0f", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0078qg3j9r3a4gci2352gtv343o4l6k2", + "diff": [{ "$unset": { "subType": "" } }] + }, + { + "_id": "0079f8qel1v4p25nmqa8d7plmjlck5cm", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "007a2sr588memfodmj6vmo3s373ku6vl", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "007btaong91i1aueuhqj3mkbdjfv6mot", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "007d5mjbogp70vjnr8t82b72afqcrucr", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "007eptebsgbdemqce1e7jl0fehc8vavj", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "007eslnt672r7irnnp5ri517n64kb0o0", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "007eslnt672r7irnnp5ri517n64kb0o0_0", + "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] + }, + { + "_id": "007fbejiiuac7t48850qmahe9v7ic4cu", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "007hr6trebge4atgf8tatgu4mlk6ihng", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "007j8br7jom1cqp4p28n7mj8qghop22i", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "007kq781j1hi9t7varptnt9tj4s3c3be", + "diff": [{ "$unset": { "subType": "" } }] + }, + { + "_id": "007mogjej2nn77h8rbe3ik8qsdgo35s2", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "007ns5rb6nh0to1mnsfdj95s9kpcn5nk", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "007pjf5soi3q94o5ba896f7vp21pqlua", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "007q94q0k1575bpgebuvr3j068fqrt86", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "007r3is1ovpb213evesvnt7m3s00h2oc", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "007tbfb52apnpp8gat4r6k98h3r6nv2q", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "007up7upgtkmekcgqdad79gq7kqi3kd3", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "007ursvpkc13oqr2edq40o1gbv7rub83", + "diff": [{ "$unset": { "percent": "", "suppressed": "" } }] + }, + { + "_id": "007vgno227aogieimi1pjjsp4p4occle", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0083mro6bi2nbq1jml2vv8df1mdcl9e0", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0084qsqgn50e8em83n995dkn3uh3ibiv", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00878olaqq67h1ik6mkbnpda324ea1la", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0089oe6giuouoma7h3lvt1cglqgtk45t", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "008aik63ll335f1qe1qe95mrl2g4e38n", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "008b9msfnsj1rv0jof8stimtr5f9g3bi", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "008bit1hos8a922i8g5iesag4kn2im8j", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "008fps2ork9n3731otmh7m25rjb125ds", + "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] + }, + { + "_id": "008fps2ork9n3731otmh7m25rjb125ds_0", + "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] + }, + { + "_id": "008gh26sbih90urq5pgrv6qslhfssqeb", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "008gh26sbih90urq5pgrv6qslhfssqeb_0", + "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] + }, + { + "_id": "008hsg72golrt9or7lipgro2cbf5hhqs", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "008i9gvupisq21ahhpdmiui035guucft", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "008je41fp50fesgcadbg1lbgs5gffjmj", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "008kf497ovbne2tu6a3mqvdqo1nfk3ba", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "008lbeiebmu2eg1hegjkat438hao3ecf", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "008rjdiu7sfcr2sfeicfb85tk68bg8ru", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "008ru0ul1l0f5kpr7h17dg45e6fcpl33", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "008s9v9ff2g1kgj0q14suba8r8u78u3h", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "008smm94h1i0kk4rrgv867t3qr5i9gg8", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "008u3jukn7s6qo69128ibgd7p5pt8k3c", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "008up7g8cfoid7seogp30dod11clotne", + "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] + }, + { + "_id": "008up7g8cfoid7seogp30dod11clotne_0", + "diff": [{ "$unset": { "suppressed": { "source": "" } } }] + }, + { + "_id": "0090h2apbmd9sc17i3ahl0tdtomadkf8", + "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] + }, + { + "_id": "0090h2apbmd9sc17i3ahl0tdtomadkf8_0", + "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] + }, + { + "_id": "0091i3hqi6jb45cvqme2li497bsu4gh4", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0091i8pmns2oh2appbtvdn8vk2godiv6", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0092gdmqqp4rpi4tgjobv230msb892tj", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00937vrp363lds5i4o93iti8p4ubca5p", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00941bse1rusk3oir9m2c3gg5i51m9eo", + "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] + }, + { + "_id": "00941bse1rusk3oir9m2c3gg5i51m9eo_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "0095ak9reeakg58a9sdo5u16aq2gqsf5", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0099ahor7c9tcd8m56ojkje1upna41gh", + "diff": [{ "$unset": { "subType": "" } }] + }, + { + "_id": "0099b74qqipdrrqg1f93ph2akgultbbn", + "diff": [{ "$unset": { "subType": "" } }] + }, + { + "_id": "009anmftasc9kidp0d9ml10brci2c287", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "009d8prcaur90hfhcvp87drc3i7n3mki", + "diff": [{ "$unset": { "subType": "" } }] + }, + { + "_id": "009ec8ldt8o1nv2kd6v33q0b0193vlb9", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "009esdmj0eccmkkju6k22j5pqc4gc0b5", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "009fbg2kclihtpfj08mhu9ubdro0fj9d", + "diff": [{ "$unset": { "suppressed": { "clockDriftOffset": "" } } }] + }, + { + "_id": "009fbg2kclihtpfj08mhu9ubdro0fj9d_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "009fssgce80qm8k21987fha1v4p7eg90", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "009gdl0l7u22o9qi82g7iusb4ccs7ib3", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "009lltpsob1t75igi6d1iv52gqg79eb1", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "009ls6fhlknhno8dj6sjvp9u8b7kbvq0", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "009o1tb4dneejn1v2kb4helr1qg4meuc", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "009qrv528ujo2agbtk5ljb2irucd1lsu", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00a4umftr4kpc4bg8uidcjm7d8ugrrte", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00a6tc02ull7mniv8jevae0eru1dvure", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00a7rvhhn17u23hogcob4cu0bfr2mbnk", + "diff": [{ "$unset": { "suppressed": { "index": "" } } }] + }, + { + "_id": "00a7rvhhn17u23hogcob4cu0bfr2mbnk_0", + "diff": [{ "$unset": { "suppressed": { "index": "" } } }] + }, + { + "_id": "00a8196cn45kd29lk9rf1f4l92kg80mb", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00a9egu2esitblp23n4alk92re21hqad", + "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] + }, + { + "_id": "00a9egu2esitblp23n4alk92re21hqad_0", + "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] + }, + { + "_id": "00adlmer1m0d64htin9924b94soht9he", + "diff": [{ "$unset": { "subType": "" } }] + }, + { + "_id": "00aj562fmn4u2kn5m6uk058gkbf1g79n", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00ak731q2gbn6m436dmu6e78u80jm5v9", + "diff": [{ "$unset": { "suppressed": { "index": "" } } }] + }, + { + "_id": "00amnuknhl68eueg1lftjdesm3np4k8q", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00amphcpherhqco8erolvoj5uf07od4a", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "00amphcpherhqco8erolvoj5uf07od4a_0", + "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] + }, + { + "_id": "00ao0tb18adh4dnklqh1suluo616r5ok", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00apqsvgc7jm6ssklb5lgibon6m10es6", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00aqif8avfqsp2jusb36300g9vtg3fth", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00arkl43ougqpc1vt58frgdbbte4tkpg", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00as323dtasn45mptn7lul2sq01u30u0", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00avhj5oogglukh91fgt7bnmk7ea96ik", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00avjhsqnvnld64rcps7nbs1difvb4fn", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00avl0g9bjvk9oh0plfdm9dliahe1bgm", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00b0f5l0rmi5vgjfqs0i6rat9ldfmks6", + "diff": [{ "$unset": { "subType": "" } }] + }, + { + "_id": "00b2hji7pk7kfjvc8oa0o7na5nqfiajm", + "diff": [{ "$unset": { "subType": "" } }] + }, + { + "_id": "00b3go5mujmq45ijrl5slc4hrrpn90rl", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00b4u66tpsebnptps8al42lddnc22r21", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00b53fusv777nrncnl7dmv5oc64auic1", + "diff": [{ "$unset": { "subType": "" } }] + }, + { + "_id": "00b6l9pqvqs3fn1s55saj6plua0j6n43", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00b876cu0spuuoe7vs3kuvhodsmv8jbd", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00ba0s1tnf4bob1lmk2um8bdn430khr2", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00banp948lntevb74c9mnus6qoqutgsl", + "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] + }, + { + "_id": "00banp948lntevb74c9mnus6qoqutgsl_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00bbnhfdl3hl92f2ucutb1iv2ug3ldm1", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00be4iinutpqbep1jr250krkheutbjlv", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00bgl9saknei3pqtdi9bt79e8cfarjnm", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00bhgfrumqssh38i8pia3ti30gfgctcs", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00bmfif6ju4uc38l5jmqjm9umv6tfsvd", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00bnlg7mbpfjvmg4orvdd3783g11s88a", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00bnlg7mbpfjvmg4orvdd3783g11s88a_0", + "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] + }, + { + "_id": "00bno9dug4u4ncus8522ese4i5v1qkeo", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00bnp0go651o085asv767ufijn6hu8ba", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00bobb7l6m0cnaua9k606ngu1kj3m8p8", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00brqbe948q5uomu382nk0ucgre6dij1", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00bsjoiu7elkq7tahcspl1apl86f4tql", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00bsjoiu7elkq7tahcspl1apl86f4tql_0", + "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] + }, + { + "_id": "00bsrlvtnr831lbsg9eui393iridhsh4", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00bsvgdd3d3aha5aes1usac41fu64svu", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00bu50k4pphqqqhcdgp3d8cvrjlsos2t", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00c26rb4pe8ttmccugpb476f7s1grsrc", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00c30aci3h3g0ue1st3p83ev7bo0f5c0", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00c6fie9s3pb6g84r9qnufv3aq067cso", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00c8864becupu8qi30s6l7bi6v0v9ja8", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00c8hsa1d72ns99uv496bsr1lb337n83", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00c8hsa1d72ns99uv496bsr1lb337n83_0", + "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] + }, + { + "_id": "00c8jq6crun5762qsl0t5hfkau42utib", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "00cfm2h86002cr06klqni7ajg7peaoah", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00ch2aieeca34l32jsmgkn05o78h1a6m", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00cjjov0uivatlqu7k41e3tgipcgif10", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00cm9ciiffd3h08t9fatpcdes594tlm7", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00cmc50gm0l4l4cpq5eshvp2oh7fuj51", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00cocsqjg2g2ruqu636uj25jie110sb6", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00csndpk8s58fl53hct5kea6hfb80i5q", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00ct63h045l0n5sepj8aecoqh2icapin", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00ctd03k7t25016opvvq8v18ng9p8s0q", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00d08clqba62glnv7fj0a9skvfl72rjf", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00d1l3qamhggiig1rf3mn35sh0ocgvt8", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00d2dq417dha4oin9j0mi0ge02nm8kq4", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00d3furp7tb1njokih8l0tt7qii0cvd3", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00d48k3nj3mrm2pe4e6pqitfp2smt4ec", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00d8ebcb4v3q2lfoj3o8qbh54shgchma", + "diff": [{ "$unset": { "subType": "" } }] + }, + { + "_id": "00d9l7o7040ifu6bf3biu7ai5cfjcfqd", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00dajc12l1l73nmblogeu157qtgvrmo2", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00dbqbdpo7hkhv3ea22cldf2jdlv9as3", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00dbu188uv4usi4jrjefucuj0qh8pjsv", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00dcc5rrpur7ppahjrdpse04t66c6ou6", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00dcc5rrpur7ppahjrdpse04t66c6ou6_0", + "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] + }, + { + "_id": "00ddv5fr5q4hg33253rvd9ajoa4cmtqd", + "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] + }, + { + "_id": "00ddv5fr5q4hg33253rvd9ajoa4cmtqd_0", + "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] + }, + { + "_id": "00dfl9nk8fa2d5foumflond3tk7hubkm", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00div16jgar0fh9miuka93roj0tdsv5l", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00dla9ek59hqt5jt0hiot620m6ujie7e", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00dldk1orv44qvmqd4nu7hsj45826soe", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00dpoopkga7ei3rh78ob7sfns3vk9fnv", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00dropqr92dil3hhvvjft42qifal33mg", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00ds9u6nq3lbl3rufq3khtd5bt4qi65e", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00dt4kud9rd0redke43lrgf9d2g548fm", + "diff": [{ "$unset": { "subType": "" } }] + }, + { + "_id": "00dvb2j21n8fj00p7ndc48o585avt5mm", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00dvq539utrfpk82q2utfpqcchq0qtea", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00e0g189gc8rnif3sgi88ebr4p15a72e", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00e22qutjqlbojj7a2moa0pubr0ptbqv", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00e2eeq17vn9bmsftk3ls7b3t6aibpch", + "diff": [{ "$unset": { "suppressed": { "index": "" } } }] + }, + { + "_id": "00e2eeq17vn9bmsftk3ls7b3t6aibpch_0", + "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] + }, + { + "_id": "003pv66tbv4ts0d7dtg87iqgfue2njko", + "diff": [ + { + "$set": { + "bgTarget": { "0": { "low": 0.24649 } }, + "insulinSensitivity": { "3": { "amount": 0.10784 } }, + "units": { "bg": "mmol/L" } + } + } + ] + }, + { + "_id": "003q3akh725mgom2o0veto788r3omfl1", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "003ra7lle4afbui5b8u3jidrs185toua", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "003tcon8tounj2qm8k1v9h5l6pbjqa3b", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "003tosu2cr1vktgaepkromj2i97ld4jk", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0040ubuoala10qr24oa9mvifpb4fl4hr", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0043bmh3l05iumq933vfc5593jg4cv9j", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0043el25dr30hrh0jr5dscnntp20ls60", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0043ql9fkrvkkoipudv8ajforvta9cbn", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00445uh1pj66f3leubc9r5sv09gdd49a", + "diff": [{ "$unset": { "subType": "" } }] + }, + { + "_id": "00466bjjo66c5tkjj2h0q8qgqqosd1jh", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0048m6q2vli52njdm708mhtm775acbuq", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004anqm480clp5a9o3e1rf48jkuqlomn", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004ci48809baufo99uljbdahjup558r4", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004em6c9cjnblofd4mo2kcqg9tlsamec", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "004em6c9cjnblofd4mo2kcqg9tlsamec_0", + "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] + }, + { + "_id": "004kh7k5t42k4ci06cmo9dkdnjfo6d9j", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004mpfpguo8imiijdd72i6ik7d375rq9", + "diff": [{ "$unset": { "deliveryContext": "" } }] + }, + { + "_id": "004or2n1c0e7l2qip119t0h3gtt1gpt8", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004pe2e6mjd0je3c6hulhbtm4ql1u0nu", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004pt4qies4j1fn3vjei18p9pkauadlu", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004qs07ruhovdab3af26eko42o4repp5", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004t10h76l4m7f1sdc08i8grb2tl3rt1", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004u2t4kvug6jm31h2pkauh5cg3ud1eb", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004u5jq5tvpd4doci5r5o14brel7u0h8", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "004vh9omub24akemqvl2qoiosohk02ig", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00555ome25877chsjcpfecenmven56ir", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "0056goqpstl5blnvu4j5ruthmh0ve8lm", + "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] + }, + { + "_id": "0056goqpstl5blnvu4j5ruthmh0ve8lm_0", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "005ce26eb8enbqki8s26lfcrese0eji0", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005d7s5s4isuv35jkqibknsodes9ee0q", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005f1u9eq431t3pecccs8n5u99p37pln", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005fc44ql8u7a9ol6f8tdu3s080dqhtp", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005ggbg3ov1odn9li2g58lkrbn3n4v5m", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005hc13gfoq5fv6daph9is1qi5p2qfin", + "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] + }, + { + "_id": "005hc13gfoq5fv6daph9is1qi5p2qfin_0", + "diff": [{ "$unset": { "suppressed": { "time": "" } } }] + }, + { + "_id": "005hj9ua01t6gohbejpg5933j8f1k95t", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005iuclbuba3mtfablgbep4967eoous1", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005jkgj5ckra1up98nolt2c5aaf84c89", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005l02s5mdlgrjegbpajcfqaps58kmqc", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005ljq54s0dqggh2u34oc3dmgej6eqp9", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005ner9db6rau554pr5hkaf56vpphpc5", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005pl16rcd4j8n67v2qg360289jtr0f9", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005ruorcd7r67ura02li9kub84gde52v", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "005utsujnbab9ajinah7qp8m70gbondn", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "00604qao66ec2sh9p922ua0lv6mfihmp", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0060tke9cuqbcdr2iijsvf82hp9o9v4j", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0062cmrelkeicsrl2lgifqsarqi6b7sb", + "diff": [{ "$unset": { "percent": "" } }] + }, + { + "_id": "0062qd8meqaglivgc4eedpcr10momkdv", + "diff": [{ "$unset": { "percent": "" } }] + } +] diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 8f08cd654c..0b4cdf71ea 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -150,8 +150,14 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { if payload := bsonData["payload"]; payload != nil { - if md, ok := payload.(*metadata.Metadata); ok { - if len(*md) == 0 { + if m, ok := payload.(*metadata.Metadata); ok { + if length := len(*m); length == 0 { + log.Printf("1 remove empty payload %s", dataType) + delete(bsonData, "payload") + } + } else if m, ok := payload.(metadata.Metadata); ok { + if length := len(m); length == 0 { + log.Printf("2 remove empty payload %s", dataType) delete(bsonData, "payload") } } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 68856cd36b..252538a0aa 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -16,9 +16,7 @@ import ( glucoseTest "github.com/tidepool-org/platform/data/types/blood/glucose/test" "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/data/types/settings/pump" - pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" - "github.com/tidepool-org/platform/metadata" metadataTest "github.com/tidepool-org/platform/metadata/test" "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" From 222cc5233ce099653be156cc983250ce2170097a Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 14 Feb 2024 11:14:04 +1300 Subject: [PATCH 208/413] generic object also --- migrations/20231128_jellyfish_migration/utils/utils.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 0b4cdf71ea..9fabf5355d 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -160,6 +160,11 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { log.Printf("2 remove empty payload %s", dataType) delete(bsonData, "payload") } + } else if m, ok := payload.(map[string]interface{}); ok { + if length := len(m); length == 0 { + log.Printf("3 remove empty payload %s", dataType) + delete(bsonData, "payload") + } } if strPayload, ok := payload.(string); ok { From 7094887ecf2d08339ffe03f8eef8df6f29188b6d Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 14 Feb 2024 11:22:42 +1300 Subject: [PATCH 209/413] moar debugging for cbg --- migrations/20231128_jellyfish_migration/utils/utils.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 9fabf5355d..24b5c93835 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -150,6 +150,10 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { if payload := bsonData["payload"]; payload != nil { + if dataType == continuous.Type { + log.Printf("CBG payload %#v", payload) + } + if m, ok := payload.(*metadata.Metadata); ok { if length := len(*m); length == 0 { log.Printf("1 remove empty payload %s", dataType) @@ -175,6 +179,7 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { } bsonData["payload"] = &payloadMetadata } + } if annotations := bsonData["annotations"]; annotations != nil { if strAnnotations, ok := annotations.(string); ok { From d0c9e3570eac2a993b8b6d149b025d54f256a35c Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 14 Feb 2024 11:29:50 +1300 Subject: [PATCH 210/413] empty payload removed --- .../20231128_jellyfish_migration/utils/utils.go | 17 +---------------- .../utils/utils_test.go | 2 +- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 24b5c93835..50fc4c2371 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -150,23 +150,8 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { if payload := bsonData["payload"]; payload != nil { - if dataType == continuous.Type { - log.Printf("CBG payload %#v", payload) - } - - if m, ok := payload.(*metadata.Metadata); ok { - if length := len(*m); length == 0 { - log.Printf("1 remove empty payload %s", dataType) - delete(bsonData, "payload") - } - } else if m, ok := payload.(metadata.Metadata); ok { - if length := len(m); length == 0 { - log.Printf("2 remove empty payload %s", dataType) - delete(bsonData, "payload") - } - } else if m, ok := payload.(map[string]interface{}); ok { + if m, ok := payload.(bson.M); ok { if length := len(m); length == 0 { - log.Printf("3 remove empty payload %s", dataType) delete(bsonData, "payload") } } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 252538a0aa..103a7d3aa7 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -201,7 +201,7 @@ var _ = Describe("back-37", func() { })) }) It("should remove the payload when it is empty", func() { - datumWithPayload["payload"] = &metadata.Metadata{} + datumWithPayload["payload"] = bson.M{} err := utils.ApplyBaseChanges(datumWithPayload, datumType) Expect(err).To(BeNil()) Expect(datumWithPayload["payload"]).To(BeNil()) From 7e545876ed9c2b183d7306d1d046547ec074b528 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 14 Feb 2024 12:18:37 +1300 Subject: [PATCH 211/413] fix reservoirchange status --- .../utils/utils.go | 7 +++++++ .../utils/utils_test.go | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 50fc4c2371..a81e9f3ac5 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -23,6 +23,7 @@ import ( "github.com/tidepool-org/platform/data/types/calculator" "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/data/types/device" + "github.com/tidepool-org/platform/data/types/device/reservoirchange" dataTypesFactory "github.com/tidepool-org/platform/data/types/factory" "github.com/tidepool-org/platform/data/types/settings/pump" errorsP "github.com/tidepool-org/platform/errors" @@ -146,6 +147,12 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { //TODO ignore these, the property is just a pointer to the actual bolus delete(bsonData, "bolus") } + case device.Type: + subType := fmt.Sprintf("%v", bsonData["subType"]) + if subType == reservoirchange.SubType { + bsonData["statusId"] = bsonData["status"] + delete(bsonData, "status") + } } if payload := bsonData["payload"]; payload != nil { diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 103a7d3aa7..7bb8550425 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -15,6 +15,8 @@ import ( "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" glucoseTest "github.com/tidepool-org/platform/data/types/blood/glucose/test" "github.com/tidepool-org/platform/data/types/common" + "github.com/tidepool-org/platform/data/types/device/reservoirchange" + dataTypesDeviceTest "github.com/tidepool-org/platform/data/types/device/test" "github.com/tidepool-org/platform/data/types/settings/pump" pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" "github.com/tidepool-org/platform/metadata" @@ -173,6 +175,23 @@ var _ = Describe("back-37", func() { Expect(cbgData["value"]).To(Equal(4.88466)) }) }) + Context("reservoirChange deviceEvent datum status string", func() { + var newReservoirChange = func() *reservoirchange.ReservoirChange { + datum := reservoirchange.New() + datum.Device = *dataTypesDeviceTest.RandomDevice() + datum.SubType = "reservoirChange" + return datum + } + It("should convert to statusId", func() { + deviceEvent := newReservoirChange() + deviceEventData := getBSONData(deviceEvent) + deviceEventData["status"] = "some-status-id" + err := utils.ApplyBaseChanges(deviceEventData, deviceEvent.Type) + Expect(err).To(BeNil()) + Expect(deviceEventData["status"]).To(BeNil()) + Expect(deviceEventData["statusId"]).To(Equal("some-status-id")) + }) + }) Context("datum with string payload", func() { var datumWithPayload primitive.M var datumType string From 85b15141d96d4e9feb4e15844c60a67e6c3fa060 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 14 Feb 2024 14:34:47 +1300 Subject: [PATCH 212/413] test BuildPlatformDatum --- .../utils/test/data.go | 37 ++------- .../utils/utils.go | 47 +---------- .../utils/utils_test.go | 83 +++++++++++++++++++ 3 files changed, 94 insertions(+), 73 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go index 128034c071..7d65d1e078 100644 --- a/migrations/20231128_jellyfish_migration/utils/test/data.go +++ b/migrations/20231128_jellyfish_migration/utils/test/data.go @@ -191,36 +191,14 @@ func tandemWizardDatum() map[string]interface{} { datum["conversionOffset"] = 0 return datum +} - /* - {"_id":"00006uv9j2d38nnf90p3945uaur4p14v", - "time":{"$date":{"$numberLong":"1682144172000"}}, - "timezoneOffset":{"$numberInt":"-300"}, - "clockDriftOffset":{"$numberInt":"-221000"}, - "conversionOffset":{"$numberInt":"0"}, - "deviceTime":"2023-04-22T01:16:12", - "deviceId":"tandemCIQ1000096506889","type":"wizard", - "recommended":{"carb":{"$numberInt":"2"},"correction":{"$numberDouble":"0.35"},"net":{"$numberDouble":"2.35"}}, - "bgInput":{"$numberDouble":"8.603659386120578"}, - "carbInput":{"$numberInt":"20"}, - "insulinOnBoard":{"$numberInt":"0"}, - "insulinCarbRatio":{"$numberInt":"0"}, - "insulinSensitivity":{"$numberInt":"0"}, - "bgTarget":{"target":{"$numberInt":"0"}}, - "bolus":"sh3j1i31f7jsvjfomuaen7s18a7f7s46", - "units":"mmol/L", - "payload":{"logIndices":[{"$numberInt":"66177"}]}, - "uploadId":"upid_7af862c1228c", - "guid":"0662f529-989a-471f-8fe3-06d601ac6a0c", - "_userId":"23ea008b-4d69-4a10-9dd5-9505b0ec1f24", - "_groupId":"7c23d7dc18", - "id":"dfgjgrs9j9av9sfd6huvilqcejr6f2uv", - "modifiedTime":{"$date":{"$numberLong":"1691609596487"}}, - "createdTime":{"$date":{"$numberLong":"1691609596487"}}, - "_version":{"$numberInt":"0"}, - "_active":true, - "_deduplicator":{"hash":"xIVlJ3lN3+f1qzYDm/2+4eHWD9MODiN0JbmanvN1wO4="}} - */ +func reservoirChangeDeviceEventDatum() map[string]interface{} { + datum := base("InsOmn-1111111111111") + datum["type"] = "deviceEvent" + datum["subType"] = "reservoirChange" + datum["status"] = "cvv61jde62b6i28bgot57f18bor5au1n" + return datum } var CBGDexcomG5MobDatum = dexG5MobDatum() @@ -229,3 +207,4 @@ var PumpSettingsCarelink = carelinkPumpSettings() var PumpSettingsOmnipod = omnipodPumpSettingsDatum() var AutomatedBasalTandem = tandemAutomatedBasalDatum() var WizardTandem = tandemWizardDatum() +var ReservoirChange = reservoirChangeDeviceEventDatum() diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index a81e9f3ac5..3c938020cf 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -32,49 +32,6 @@ import ( structureValidator "github.com/tidepool-org/platform/structure/validator" ) -// func updateIfExistsPumpSettingsSleepSchedules(bsonData bson.M) (*pump.SleepScheduleMap, error) { -// //TODO: currently an array but should be a map for consistency. On pump is "Sleep Schedule 1", "Sleep Schedule 2" -// scheduleNames := map[int]string{0: "1", 1: "2"} - -// if schedules := bsonData["sleepSchedules"]; schedules != nil { -// sleepScheduleMap := pump.SleepScheduleMap{} -// dataBytes, err := json.Marshal(schedules) -// if err != nil { -// return nil, err -// } -// schedulesArray := []*pump.SleepSchedule{} -// err = json.Unmarshal(dataBytes, &schedulesArray) -// if err != nil { -// return nil, err -// } -// for i, schedule := range schedulesArray { -// days := schedule.Days -// updatedDays := []string{} -// for _, day := range *days { -// if !slices.Contains(common.DaysOfWeek(), strings.ToLower(day)) { -// return nil, errorsP.Newf("pumpSettings.sleepSchedules has an invalid day of week %s", day) -// } -// updatedDays = append(updatedDays, strings.ToLower(day)) -// } -// schedule.Days = &updatedDays -// sleepScheduleMap[scheduleNames[i]] = schedule -// } -// //sorts schedules based on day -// sleepScheduleMap.Normalize(dataNormalizer.New()) -// return &sleepScheduleMap, nil -// } -// return nil, nil -// } - -// func pumpSettingsHasBolus(bsonData bson.M) bool { -// if bolus := bsonData["bolus"]; bolus != nil { -// if _, ok := bolus.(*pump.BolusMap); ok { -// return true -// } -// } -// return false -// } - func logDiff(id string, updates interface{}) { updatesJSON, _ := json.Marshal(updates) if string(updatesJSON) != "[]" { @@ -205,12 +162,13 @@ func BuildPlatformDatum(objID string, objType string, objectData map[string]inte validator.String("_userId", parser.String("_userId")).Exists() validator.Int("_version", parser.Int("_version")).Exists() validator.Int("_schemaVersion", parser.Int("_schemaVersion")) - validator.Object("_deduplicator", parser.Object("_deduplicator")).Exists() + validator.Object("_deduplicator", parser.Object("_deduplicator")) validator.String("uploadId", parser.String("uploadId")).Exists() validator.String("guid", parser.String("guid")) validator.Time("createdTime", parser.Time("createdTime", time.RFC3339Nano)).Exists() validator.Time("modifiedTime", parser.Time("modifiedTime", time.RFC3339Nano)) + validator.Time("localTime", parser.Time("localTime", time.RFC3339Nano)) //parsed but not used in the platform //deletes will be created from the diff @@ -226,6 +184,7 @@ func BuildPlatformDatum(objID string, objType string, objectData map[string]inte case device.Type: validator.Object("previous", parser.Object("previous")) validator.Int("index", parser.Int("index")) + validator.String("statusId", parser.String("statusId")) } parser.NotParsed() diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 7bb8550425..95ecfaa9d1 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -12,9 +12,12 @@ import ( "go.mongodb.org/mongo-driver/bson/primitive" "github.com/tidepool-org/platform/data/blood/glucose" + "github.com/tidepool-org/platform/data/types/basal" "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" glucoseTest "github.com/tidepool-org/platform/data/types/blood/glucose/test" + "github.com/tidepool-org/platform/data/types/calculator" "github.com/tidepool-org/platform/data/types/common" + "github.com/tidepool-org/platform/data/types/device" "github.com/tidepool-org/platform/data/types/device/reservoirchange" dataTypesDeviceTest "github.com/tidepool-org/platform/data/types/device/test" "github.com/tidepool-org/platform/data/types/settings/pump" @@ -34,6 +37,86 @@ var _ = Describe("back-37", func() { return bsonData } + var _ = Describe("BuildPlatformDatum", func() { + + var setup = func(testObj map[string]interface{}) (map[string]interface{}, error) { + bsonData := getBSONData(testObj) + objType := fmt.Sprintf("%v", bsonData["type"]) + utils.ApplyBaseChanges(bsonData, objType) + incomingJSONData, err := json.Marshal(bsonData) + if err != nil { + return nil, err + } + cleanedObject := map[string]interface{}{} + if err := json.Unmarshal(incomingJSONData, &cleanedObject); err != nil { + return nil, err + } + return cleanedObject, nil + } + + It("should successfully build basal datum", func() { + basalData, err := setup(test.AutomatedBasalTandem) + Expect(err).To(BeNil()) + datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", basalData["_id"]), basal.Type, basalData) + Expect(err).To(BeNil()) + Expect(datum).ToNot(BeNil()) + Expect((*datum).GetType()).To(Equal(basal.Type)) + }) + + It("should successfully build dexcom g5 datum", func() { + cbgData, err := setup(test.CBGDexcomG5MobDatum) + Expect(err).To(BeNil()) + datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", cbgData["_id"]), continuous.Type, cbgData) + Expect(err).To(BeNil()) + Expect(datum).ToNot(BeNil()) + Expect((*datum).GetType()).To(Equal(continuous.Type)) + }) + + It("should successfully build carelink pump settings", func() { + pSettingsData, err := setup(test.PumpSettingsCarelink) + Expect(err).To(BeNil()) + datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", pSettingsData["_id"]), pump.Type, pSettingsData) + Expect(err).To(BeNil()) + Expect(datum).ToNot(BeNil()) + Expect((*datum).GetType()).To(Equal(pump.Type)) + }) + It("should successfully build omnipod pump settings", func() { + pSettingsData, err := setup(test.PumpSettingsOmnipod) + Expect(err).To(BeNil()) + datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", pSettingsData["_id"]), pump.Type, pSettingsData) + Expect(err).To(BeNil()) + Expect(datum).ToNot(BeNil()) + Expect((*datum).GetType()).To(Equal(pump.Type)) + }) + It("should successfully build tandem pump settings", func() { + pSettingsData, err := setup(test.PumpSettingsTandem) + Expect(err).To(BeNil()) + datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", pSettingsData["_id"]), pump.Type, pSettingsData) + Expect(err).To(BeNil()) + Expect(datum).ToNot(BeNil()) + Expect((*datum).GetType()).To(Equal(pump.Type)) + }) + It("should successfully build tandem wizard", func() { + Skip("todo sort out /duration, /percent and /rate") + calcData, err := setup(test.WizardTandem) + Expect(err).To(BeNil()) + datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", calcData["_id"]), calculator.Type, calcData) + Expect(err).To(BeNil()) + Expect(datum).ToNot(BeNil()) + Expect((*datum).GetType()).To(Equal(calculator.Type)) + }) + + It("should successfully build device event", func() { + deviceEventData, err := setup(test.ReservoirChange) + Expect(err).To(BeNil()) + datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", deviceEventData["_id"]), device.Type, deviceEventData) + Expect(err).To(BeNil()) + Expect(datum).ToNot(BeNil()) + Expect((*datum).GetType()).To(Equal(device.Type)) + }) + + }) + var _ = Describe("ApplyBaseChanges", func() { const expectedID = "some-id" From 94eafcbd66d4b866a501a286fc76e108393cd486 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 14 Feb 2024 16:46:24 +1300 Subject: [PATCH 213/413] fix for cgmSettings precision --- .../utils/test/data.go | 36 +++++++++++++++ .../utils/utils.go | 46 +++++++++++++++---- .../utils/utils_test.go | 10 ++++ 3 files changed, 82 insertions(+), 10 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go index 7d65d1e078..142a051923 100644 --- a/migrations/20231128_jellyfish_migration/utils/test/data.go +++ b/migrations/20231128_jellyfish_migration/utils/test/data.go @@ -201,6 +201,41 @@ func reservoirChangeDeviceEventDatum() map[string]interface{} { return datum } +func cgmSettingsDatum() map[string]interface{} { + datum := base("DexG5MobRec-1111111111111") + datum["type"] = "cgmSettings" + datum["units"] = "mmol/L" + + datum["lowAlerts"] = map[string]interface{}{ + "enabled": true, + "level": 3.8855235937318735, + "snooze": 900000, + } + + datum["highAlerts"] = map[string]interface{}{ + "enabled": true, + "level": 22.202991964182132, + "snooze": 0, + } + + datum["rateOfChangeAlerts"] = map[string]interface{}{ + "fallRate": map[string]interface{}{ + "enabled": false, + "rate": -0.16652243973136602, + }, + "riseRate": map[string]interface{}{ + "enabled": false, + "rate": 0.16652243973136602, + }, + } + + datum["outOfRangeAlerts"] = map[string]interface{}{ + "enabled": true, + "snooze": 1200000, + } + return datum +} + var CBGDexcomG5MobDatum = dexG5MobDatum() var PumpSettingsTandem = tandemPumpSettingsDatum() var PumpSettingsCarelink = carelinkPumpSettings() @@ -208,3 +243,4 @@ var PumpSettingsOmnipod = omnipodPumpSettingsDatum() var AutomatedBasalTandem = tandemAutomatedBasalDatum() var WizardTandem = tandemWizardDatum() var ReservoirChange = reservoirChangeDeviceEventDatum() +var CGMSetting = cgmSettingsDatum() diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 3c938020cf..286a807456 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -25,6 +25,7 @@ import ( "github.com/tidepool-org/platform/data/types/device" "github.com/tidepool-org/platform/data/types/device/reservoirchange" dataTypesFactory "github.com/tidepool-org/platform/data/types/factory" + "github.com/tidepool-org/platform/data/types/settings/cgm" "github.com/tidepool-org/platform/data/types/settings/pump" errorsP "github.com/tidepool-org/platform/errors" "github.com/tidepool-org/platform/metadata" @@ -46,6 +47,22 @@ func logDiff(id string, updates interface{}) { } } +func getBGValuePrecision(val interface{}) *float64 { + floatStr := fmt.Sprintf("%v", val) + floatParts := strings.Split(floatStr, ".") + if len(floatParts) == 2 { + if len(floatParts[1]) > 5 { + if floatVal, ok := val.(float64); ok { + mgdlVal := floatVal * glucose.MmolLToMgdLConversionFactor + intValue := int(mgdlVal/glucose.MmolLToMgdLConversionFactor*glucose.MmolLToMgdLPrecisionFactor + 0.5) + floatValue := float64(intValue) / glucose.MmolLToMgdLPrecisionFactor + return &floatValue + } + } + } + return nil +} + func ApplyBaseChanges(bsonData bson.M, dataType string) error { switch dataType { @@ -86,16 +103,24 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { case selfmonitored.Type, ketone.Type, continuous.Type: units := fmt.Sprintf("%v", bsonData["units"]) if units == glucose.MmolL || units == glucose.Mmoll { - floatStr := fmt.Sprintf("%v", bsonData["value"]) - floatParts := strings.Split(floatStr, ".") - if len(floatParts) == 2 { - if len(floatParts[1]) > 5 { - if floatVal, ok := bsonData["value"].(float64); ok { - mgdlVal := floatVal * glucose.MmolLToMgdLConversionFactor - intValue := int(mgdlVal/glucose.MmolLToMgdLConversionFactor*glucose.MmolLToMgdLPrecisionFactor + 0.5) - floatValue := float64(intValue) / glucose.MmolLToMgdLPrecisionFactor - bsonData["value"] = floatValue - } + if val := getBGValuePrecision(bsonData["value"]); val != nil { + bsonData["value"] = *val + } + } + case cgm.Type: + units := fmt.Sprintf("%v", bsonData["units"]) + if units == glucose.MmolL || units == glucose.Mmoll { + + if lowAlerts, ok := bsonData["lowAlerts"].(bson.M); ok { + if val := getBGValuePrecision(lowAlerts["level"]); val != nil { + lowAlerts["level"] = *val + bsonData["lowAlerts"] = lowAlerts + } + } + if highAlerts, ok := bsonData["highAlerts"].(bson.M); ok { + if val := getBGValuePrecision(highAlerts["level"]); val != nil { + highAlerts["level"] = *val + bsonData["highAlerts"] = highAlerts } } } @@ -181,6 +206,7 @@ func BuildPlatformDatum(objID string, objType string, objectData map[string]inte case basal.Type: validator.Object("suppressed", parser.Object("suppressed")) validator.Float64("percent", parser.Float64("percent")) + validator.Float64("rate", parser.Float64("rate")) case device.Type: validator.Object("previous", parser.Object("previous")) validator.Int("index", parser.Int("index")) diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 95ecfaa9d1..9d4991aec9 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -20,6 +20,7 @@ import ( "github.com/tidepool-org/platform/data/types/device" "github.com/tidepool-org/platform/data/types/device/reservoirchange" dataTypesDeviceTest "github.com/tidepool-org/platform/data/types/device/test" + "github.com/tidepool-org/platform/data/types/settings/cgm" "github.com/tidepool-org/platform/data/types/settings/pump" pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" "github.com/tidepool-org/platform/metadata" @@ -115,6 +116,15 @@ var _ = Describe("back-37", func() { Expect((*datum).GetType()).To(Equal(device.Type)) }) + It("should successfully build cgm settings", func() { + deviceEventData, err := setup(test.CGMSetting) + Expect(err).To(BeNil()) + datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", deviceEventData["_id"]), cgm.Type, deviceEventData) + Expect(err).To(BeNil()) + Expect(datum).ToNot(BeNil()) + Expect((*datum).GetType()).To(Equal(cgm.Type)) + }) + }) var _ = Describe("ApplyBaseChanges", func() { From 5456c144685e6f522c7afc5d28467d2a76385c8a Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 14 Feb 2024 17:18:01 +1300 Subject: [PATCH 214/413] parse previousOverride allow string alarm status --- migrations/20231128_jellyfish_migration/utils/utils.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 286a807456..8c8c1516f2 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -23,6 +23,7 @@ import ( "github.com/tidepool-org/platform/data/types/calculator" "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/data/types/device" + "github.com/tidepool-org/platform/data/types/device/alarm" "github.com/tidepool-org/platform/data/types/device/reservoirchange" dataTypesFactory "github.com/tidepool-org/platform/data/types/factory" "github.com/tidepool-org/platform/data/types/settings/cgm" @@ -110,7 +111,6 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { case cgm.Type: units := fmt.Sprintf("%v", bsonData["units"]) if units == glucose.MmolL || units == glucose.Mmoll { - if lowAlerts, ok := bsonData["lowAlerts"].(bson.M); ok { if val := getBGValuePrecision(lowAlerts["level"]); val != nil { lowAlerts["level"] = *val @@ -131,7 +131,8 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { } case device.Type: subType := fmt.Sprintf("%v", bsonData["subType"]) - if subType == reservoirchange.SubType { + switch subType { + case reservoirchange.SubType, alarm.SubType: bsonData["statusId"] = bsonData["status"] delete(bsonData, "status") } @@ -209,6 +210,7 @@ func BuildPlatformDatum(objID string, objType string, objectData map[string]inte validator.Float64("rate", parser.Float64("rate")) case device.Type: validator.Object("previous", parser.Object("previous")) + validator.String("previousOverride", parser.String("previousOverride")) validator.Int("index", parser.Int("index")) validator.String("statusId", parser.String("statusId")) } From b075de8fcea3217c4fc119b113356af0a04fbab5 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 15 Feb 2024 09:50:31 +1300 Subject: [PATCH 215/413] hold off writing errors until the end --- .../jellyfish_migration.go | 82 +---------------- .../utils/migrationUtil.go | 90 ++++++++++++------- 2 files changed, 58 insertions(+), 114 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 5ddfa45c27..a603b6f3e0 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -184,85 +184,6 @@ func (m *Migration) getDataCollection() *mongo.Collection { return m.client.Database("data").Collection("deviceData") } -// TODO: switch to audit + update -// func (m *Migration) fetchAndUpdateBatch() bool { - -// selector := bson.M{ -// "_deduplicator": bson.M{"$exists": false}, -// } - -// if strings.TrimSpace(m.config.userID) != "" { -// log.Printf("fetching for user %s", m.config.userID) -// selector["_userId"] = m.config.userID -// } - -// // jellyfish uses a generated _id that is not an mongo objectId -// idNotObjectID := bson.M{"$not": bson.M{"$type": "objectId"}} - -// if lastID := m.migrationUtil.GetLastID(); lastID != "" { -// selector["$and"] = []interface{}{ -// bson.M{"_id": bson.M{"$gt": lastID}}, -// bson.M{"_id": idNotObjectID}, -// } -// } else { -// selector["_id"] = idNotObjectID -// } - -// batchSize := int32(m.config.queryBatchSize) - -// if dataC := m.getDataCollection(); dataC != nil { - -// dDataCursor, err := dataC.Find(m.ctx, selector, -// &options.FindOptions{ -// Sort: bson.M{"_id": 1}, -// BatchSize: &batchSize, -// Limit: &m.config.queryLimit, -// }, -// ) -// if err != nil { -// log.Printf("failed to select data: %s", err) -// return false -// } -// defer dDataCursor.Close(m.ctx) - -// updateStart := time.Now() - -// for dDataCursor.Next(m.ctx) { - -// item := bson.M{} -// if err := dDataCursor.Decode(&item); err != nil { -// log.Printf("error decoding data: %s", err) -// return false -// } - -// datumID, datumUpdates, err := utils.GetDatumUpdates(item) -// if err != nil { -// m.migrationUtil.OnError(err, datumID, "failed applying updates") -// continue -// } -// for _, update := range datumUpdates { -// updateOp := mongo.NewUpdateOneModel() -// if update["$rename"] != nil { -// log.Printf("rename op, 2 ops for same datum") -// updateOp.SetFilter(bson.M{"_id": datumID}) -// } else { -// updateOp.SetFilter(bson.M{"_id": datumID, "modifiedTime": item["modifiedTime"]}) -// } -// updateOp.SetUpdate(update) -// m.migrationUtil.SetUpdates(updateOp) -// m.migrationUtil.SetLastProcessed(datumID) -// } -// } -// stats := m.migrationUtil.GetStats() -// if stats.Errored > 0 { -// log.Printf("update took [%s] for [%d] items with [%d] errors", time.Since(updateStart), stats.ToApply, stats.Errored) -// } -// return stats.ToApply > 0 -// } -// return false -// } - -// TODO: switch to audit + update func (m *Migration) fetchAndProcess() bool { selector := bson.M{} @@ -313,7 +234,7 @@ func (m *Migration) fetchAndProcess() bool { itemType := fmt.Sprintf("%v", item["type"]) updates, err := utils.ProcessDatum(itemID, itemType, item, m.config.audit) if err != nil { - m.migrationUtil.OnError(err, itemID, itemType, fmt.Sprintf("[type=%s]", itemType)) + m.migrationUtil.OnError(utils.ErrorData{Error: err, ItemID: itemID, ItemType: itemType, Msg: fmt.Sprintf("[type=%s]", itemType)}) } if !m.config.audit { for _, update := range updates { @@ -327,6 +248,7 @@ func (m *Migration) fetchAndProcess() bool { all = append(all, item) } m.migrationUtil.SetFetched(all) + //should we write errors here as intermediate step? return len(all) > 0 } return false diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 8125d4a5a0..922d1266e7 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -41,6 +41,7 @@ type migrationUtil struct { client *mongo.Client config *MigrationUtilConfig updates []mongo.WriteModel + groupedErrors map[string][]ErrorData rawData []bson.M errorsCount int updatedCount int @@ -48,6 +49,13 @@ type migrationUtil struct { startedAt time.Time } +type ErrorData struct { + Error error + ItemID string + ItemType string + Msg string +} + type MigrationStats struct { Errored int Fetched int @@ -59,7 +67,7 @@ type MigrationStats struct { type MigrationUtil interface { Initialize(ctx context.Context, dataC *mongo.Collection) error Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func() bool) error - OnError(reportErr error, datumID string, datumType string, msg string) + OnError(data ErrorData) SetUpdates(update ...*mongo.UpdateOneModel) SetLastProcessed(lastID string) SetFetched(raw []bson.M) @@ -83,13 +91,14 @@ func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client, lastID } m := &migrationUtil{ - client: client, - config: config, - updates: []mongo.WriteModel{}, - rawData: []bson.M{}, - errorsCount: 0, - updatedCount: 0, - startedAt: time.Now(), + client: client, + config: config, + updates: []mongo.WriteModel{}, + rawData: []bson.M{}, + groupedErrors: map[string][]ErrorData{}, + errorsCount: 0, + updatedCount: 0, + startedAt: time.Now(), } if lastID != nil { m.lastUpdatedId = *lastID @@ -122,12 +131,15 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe for fetchAndUpdateFn() { if err := m.writeUpdates(ctx, dataC); err != nil { log.Printf("failed writing batch: %s", err) + // dump errors first + m.writeErrors() return err } if m.capReached() { break } } + m.writeErrors() m.GetStats().report() return nil } @@ -142,6 +154,36 @@ func (m *migrationUtil) SetLastProcessed(lastID string) { m.lastUpdatedId = lastID } +func (m *migrationUtil) writeErrors() { + var errFormat = "[_id=%s] %s %s\n" + logName := "error.log" + for group, errors := range m.groupedErrors { + if group != "" { + logName = fmt.Sprintf("error_%s.log", group) + } + formatedErrors := []string{} + + for _, errData := range errors { + errJSON, err := json.Marshal(errData.Error) + if err != nil { + log.Println(err) + os.Exit(1) + } + formatedErrors = append(formatedErrors, fmt.Sprintf(errFormat, errData.ItemID, errData.Msg, string(errJSON))) + } + + f, err := os.OpenFile(logName, + os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Println(err) + os.Exit(1) + } + defer f.Close() + f.WriteString(strings.Join(formatedErrors, "\n")) + m.groupedErrors[group] = []ErrorData{} + } +} + func (m *migrationUtil) SetFetched(raw []bson.M) { m.rawData = append(m.rawData, raw...) } @@ -223,34 +265,14 @@ func (c *MigrationUtilConfig) SetStopOnErr(stopOnErr bool) *MigrationUtilConfig // OnError // - write error to file `error.log` in directory cli is running in // - optionally stop the operation if stopOnErr is true in the config -func (m *migrationUtil) OnError(reportErr error, datumID string, datumType string, msg string) { +func (m *migrationUtil) OnError(data ErrorData) { + m.errorsCount++ + m.groupedErrors[data.ItemType] = append(m.groupedErrors[data.ItemType], data) var errFormat = "[_id=%s] %s %s\n" - if reportErr != nil { - m.errorsCount++ - - logName := "error.log" - if datumType != "" { - logName = fmt.Sprintf("error_%s.log", datumType) - } - f, err := os.OpenFile(logName, - os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - log.Println(err) - os.Exit(1) - } - defer f.Close() - - errBytes, err := json.Marshal(reportErr) - if err != nil { - log.Println(err) - os.Exit(1) - } - f.WriteString(fmt.Sprintf("[_id=%s] %s %s\n", datumID, msg, string(errBytes))) - if m.config.stopOnErr { - log.Printf(errFormat, datumID, msg, reportErr.Error()) - os.Exit(1) - } + if m.config.stopOnErr { + log.Printf(errFormat, data.ItemID, data.Msg, data.Error.Error()) + os.Exit(1) } } From 3f97d79eb5f05ed42ca53ed918ffe0c9c83ff80a Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 15 Feb 2024 10:18:40 +1300 Subject: [PATCH 216/413] all errors to JSON at once --- .../jellyfish_migration.go | 2 +- .../utils/migrationUtil.go | 24 +++++++------------ 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index a603b6f3e0..0027e96339 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -234,7 +234,7 @@ func (m *Migration) fetchAndProcess() bool { itemType := fmt.Sprintf("%v", item["type"]) updates, err := utils.ProcessDatum(itemID, itemType, item, m.config.audit) if err != nil { - m.migrationUtil.OnError(utils.ErrorData{Error: err, ItemID: itemID, ItemType: itemType, Msg: fmt.Sprintf("[type=%s]", itemType)}) + m.migrationUtil.OnError(utils.ErrorData{Error: err, ItemID: itemID, ItemType: itemType}) } if !m.config.audit { for _, update := range updates { diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 922d1266e7..8815ad41dd 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -50,10 +50,10 @@ type migrationUtil struct { } type ErrorData struct { - Error error - ItemID string - ItemType string - Msg string + Error error `json:"error"` + ItemID string `json:"_id"` + ItemType string `json:"-"` + Msg string `json:"message,omitempty"` } type MigrationStats struct { @@ -155,21 +155,15 @@ func (m *migrationUtil) SetLastProcessed(lastID string) { } func (m *migrationUtil) writeErrors() { - var errFormat = "[_id=%s] %s %s\n" logName := "error.log" for group, errors := range m.groupedErrors { if group != "" { logName = fmt.Sprintf("error_%s.log", group) } - formatedErrors := []string{} - - for _, errData := range errors { - errJSON, err := json.Marshal(errData.Error) - if err != nil { - log.Println(err) - os.Exit(1) - } - formatedErrors = append(formatedErrors, fmt.Sprintf(errFormat, errData.ItemID, errData.Msg, string(errJSON))) + errorsJSON, err := json.Marshal(errors) + if err != nil { + log.Println(err) + os.Exit(1) } f, err := os.OpenFile(logName, @@ -179,7 +173,7 @@ func (m *migrationUtil) writeErrors() { os.Exit(1) } defer f.Close() - f.WriteString(strings.Join(formatedErrors, "\n")) + f.WriteString(string(errorsJSON)) m.groupedErrors[group] = []ErrorData{} } } From d44dd3125de3097b76f9424b87b238c768c433a0 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 15 Feb 2024 10:58:35 +1300 Subject: [PATCH 217/413] errors as we write updates smaller files --- .../utils/migrationUtil.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 8815ad41dd..d203d11705 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -132,15 +132,16 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe if err := m.writeUpdates(ctx, dataC); err != nil { log.Printf("failed writing batch: %s", err) // dump errors first - m.writeErrors() + m.writeErrors(m.GetStats()) return err } if m.capReached() { break } } - m.writeErrors() - m.GetStats().report() + stats := m.GetStats() + m.writeErrors(stats) + stats.report() return nil } @@ -154,11 +155,11 @@ func (m *migrationUtil) SetLastProcessed(lastID string) { m.lastUpdatedId = lastID } -func (m *migrationUtil) writeErrors() { - logName := "error.log" +func (m *migrationUtil) writeErrors(stats MigrationStats) { + logName := "logs/error.log" for group, errors := range m.groupedErrors { if group != "" { - logName = fmt.Sprintf("error_%s.log", group) + logName = fmt.Sprintf("logs/error_%s_%s.log", group, stats.Elapsed.String()) } errorsJSON, err := json.Marshal(errors) if err != nil { @@ -320,7 +321,6 @@ func (m *migrationUtil) getOplogDuration(ctx context.Context) (time.Duration, er log.Println("Not clustered, not retrieving oplog duration.") oplogDuration := time.Duration(m.config.minOplogWindow+1) * time.Second return oplogDuration, nil - } func (m *migrationUtil) setWriteBatchSize(ctx context.Context) error { @@ -483,7 +483,9 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio log.Println("dry-run so no changes applied") } else { log.Printf("write took [%s] for [%d] items\n", time.Since(writeStart), writtenCount) - m.GetStats().report() + stats := m.GetStats() + stats.report() + m.writeErrors(stats) } return nil } From f02369de6d2627686f0fe47eaa48e998d0b2b6f9 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 15 Feb 2024 11:41:05 +1300 Subject: [PATCH 218/413] cleaner error logs and grouping --- .../utils/migrationUtil.go | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index d203d11705..60e7224ed1 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -41,7 +41,7 @@ type migrationUtil struct { client *mongo.Client config *MigrationUtilConfig updates []mongo.WriteModel - groupedErrors map[string][]ErrorData + groupedErrors groupedErrors rawData []bson.M errorsCount int updatedCount int @@ -56,6 +56,19 @@ type ErrorData struct { Msg string `json:"message,omitempty"` } +type groupedErrors map[string][]ErrorData + +func (g groupedErrors) count() int { + max := 0 + for _, errs := range g { + gCount := len(errs) + if gCount > max { + max = gCount + } + } + return max +} + type MigrationStats struct { Errored int Fetched int @@ -95,7 +108,7 @@ func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client, lastID config: config, updates: []mongo.WriteModel{}, rawData: []bson.M{}, - groupedErrors: map[string][]ErrorData{}, + groupedErrors: groupedErrors{}, errorsCount: 0, updatedCount: 0, startedAt: time.Now(), @@ -132,16 +145,15 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe if err := m.writeUpdates(ctx, dataC); err != nil { log.Printf("failed writing batch: %s", err) // dump errors first - m.writeErrors(m.GetStats()) + m.writeErrors() return err } if m.capReached() { break } } - stats := m.GetStats() - m.writeErrors(stats) - stats.report() + m.GetStats().report() + m.writeErrors() return nil } @@ -155,11 +167,12 @@ func (m *migrationUtil) SetLastProcessed(lastID string) { m.lastUpdatedId = lastID } -func (m *migrationUtil) writeErrors(stats MigrationStats) { +func (m *migrationUtil) writeErrors() { + timestamp := strings.Replace(time.Now().Format(time.Stamp), " ", "-", -1) logName := "logs/error.log" for group, errors := range m.groupedErrors { if group != "" { - logName = fmt.Sprintf("logs/error_%s_%s.log", group, stats.Elapsed.String()) + logName = fmt.Sprintf("logs/error_%s_%s.log", group, timestamp) } errorsJSON, err := json.Marshal(errors) if err != nil { @@ -483,9 +496,10 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio log.Println("dry-run so no changes applied") } else { log.Printf("write took [%s] for [%d] items\n", time.Since(writeStart), writtenCount) - stats := m.GetStats() - stats.report() - m.writeErrors(stats) + m.GetStats().report() + if m.groupedErrors.count() > 500 { + m.writeErrors() + } } return nil } From 9d7a0e5bc932c7255d369afb5229a72181762ccc Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 15 Feb 2024 12:00:09 +1300 Subject: [PATCH 219/413] limit per group --- .../utils/migrationUtil.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 60e7224ed1..d03c97eeb0 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -145,7 +145,7 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe if err := m.writeUpdates(ctx, dataC); err != nil { log.Printf("failed writing batch: %s", err) // dump errors first - m.writeErrors() + m.writeErrors(nil) return err } if m.capReached() { @@ -153,7 +153,7 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe } } m.GetStats().report() - m.writeErrors() + m.writeErrors(nil) return nil } @@ -167,10 +167,18 @@ func (m *migrationUtil) SetLastProcessed(lastID string) { m.lastUpdatedId = lastID } -func (m *migrationUtil) writeErrors() { +func (m *migrationUtil) writeErrors(groupLimit *int) { + timestamp := strings.Replace(time.Now().Format(time.Stamp), " ", "-", -1) logName := "logs/error.log" for group, errors := range m.groupedErrors { + + if groupLimit != nil { + if len(errors) < *groupLimit { + continue + } + } + if group != "" { logName = fmt.Sprintf("logs/error_%s_%s.log", group, timestamp) } @@ -496,10 +504,9 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio log.Println("dry-run so no changes applied") } else { log.Printf("write took [%s] for [%d] items\n", time.Since(writeStart), writtenCount) + errorWriteLimit := 500 m.GetStats().report() - if m.groupedErrors.count() > 500 { - m.writeErrors() - } + m.writeErrors(&errorWriteLimit) } return nil } From 8661d317977c82a2d8584d73b98745ef2272751b Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 15 Feb 2024 13:53:16 +1300 Subject: [PATCH 220/413] write errors as pretty JSON --- .../utils/migrationUtil.go | 22 +- .../utils/utils.go | 201 ------------------ 2 files changed, 8 insertions(+), 215 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index d03c97eeb0..883c490129 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -41,6 +41,7 @@ type migrationUtil struct { client *mongo.Client config *MigrationUtilConfig updates []mongo.WriteModel + dataUpdates []Update groupedErrors groupedErrors rawData []bson.M errorsCount int @@ -49,6 +50,11 @@ type migrationUtil struct { startedAt time.Time } +type Update struct { + ItemID string `json:"_id"` + MongoWrites []mongo.WriteModel `json:"diff"` +} + type ErrorData struct { Error error `json:"error"` ItemID string `json:"_id"` @@ -58,17 +64,6 @@ type ErrorData struct { type groupedErrors map[string][]ErrorData -func (g groupedErrors) count() int { - max := 0 - for _, errs := range g { - gCount := len(errs) - if gCount > max { - max = gCount - } - } - return max -} - type MigrationStats struct { Errored int Fetched int @@ -109,6 +104,7 @@ func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client, lastID updates: []mongo.WriteModel{}, rawData: []bson.M{}, groupedErrors: groupedErrors{}, + dataUpdates: []Update{}, errorsCount: 0, updatedCount: 0, startedAt: time.Now(), @@ -168,7 +164,6 @@ func (m *migrationUtil) SetLastProcessed(lastID string) { } func (m *migrationUtil) writeErrors(groupLimit *int) { - timestamp := strings.Replace(time.Now().Format(time.Stamp), " ", "-", -1) logName := "logs/error.log" for group, errors := range m.groupedErrors { @@ -178,11 +173,10 @@ func (m *migrationUtil) writeErrors(groupLimit *int) { continue } } - if group != "" { logName = fmt.Sprintf("logs/error_%s_%s.log", group, timestamp) } - errorsJSON, err := json.Marshal(errors) + errorsJSON, err := json.MarshalIndent(errors, "", " ") if err != nil { log.Println(err) os.Exit(1) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 8c8c1516f2..5e735e9956 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -352,204 +352,3 @@ func ProcessDatum(dataID string, dataType string, bsonData bson.M, logChanges bo } return updates, nil } - -// func GetDatumUpdates(bsonData bson.M) (string, []bson.M, error) { -// updates := []bson.M{} -// set := bson.M{} -// var rename bson.M -// var identityFields []string - -// datumID, ok := bsonData["_id"].(string) -// if !ok { -// return "", nil, errorsP.New("cannot get the datum id") -// } - -// datumType, ok := bsonData["type"].(string) -// if !ok { -// return datumID, nil, errorsP.New("cannot get the datum type") -// } - -// // TODO: based on discussions we want to ensure that these are the correct type -// // even though we are not using them for the hash generation -// delete(bsonData, "payload") -// delete(bsonData, "annotations") - -// switch datumType { -// case basal.Type: -// var datum *basal.Basal -// dataBytes, err := bson.Marshal(bsonData) -// if err != nil { -// return datumID, nil, err -// } -// err = bson.Unmarshal(dataBytes, &datum) -// if err != nil { -// return datumID, nil, err -// } -// identityFields, err = datum.IdentityFields() -// if err != nil { -// return datumID, nil, err -// } -// case bolus.Type: -// var datum *bolus.Bolus -// dataBytes, err := bson.Marshal(bsonData) -// if err != nil { -// return datumID, nil, err -// } -// err = bson.Unmarshal(dataBytes, &datum) -// if err != nil { -// return datumID, nil, err -// } -// identityFields, err = datum.IdentityFields() -// if err != nil { -// return datumID, nil, err -// } -// case device.Type: -// var datum bolus.Bolus -// dataBytes, err := bson.Marshal(bsonData) -// if err != nil { -// return datumID, nil, err -// } -// err = bson.Unmarshal(dataBytes, &datum) -// if err != nil { -// return datumID, nil, err -// } -// identityFields, err = datum.IdentityFields() -// if err != nil { -// return datumID, nil, err -// } -// case pump.Type: -// var datum types.Base -// dataBytes, err := bson.Marshal(bsonData) -// if err != nil { -// return datumID, nil, err -// } -// err = bson.Unmarshal(dataBytes, &datum) -// if err != nil { -// return datumID, nil, err -// } -// identityFields, err = datum.IdentityFields() -// if err != nil { -// return datumID, nil, err -// } - -// if pumpSettingsHasBolus(bsonData) { -// rename = bson.M{"bolus": "boluses"} -// } - -// sleepSchedules, err := updateIfExistsPumpSettingsSleepSchedules(bsonData) -// if err != nil { -// return datumID, nil, err -// } else if sleepSchedules != nil { -// set["sleepSchedules"] = sleepSchedules -// } -// case selfmonitored.Type: -// var datum selfmonitored.SelfMonitored -// dataBytes, err := bson.Marshal(bsonData) -// if err != nil { -// return datumID, nil, err -// } -// err = bson.Unmarshal(dataBytes, &datum) -// if err != nil { -// return datumID, nil, err -// } -// beforeVal := datum.Value -// beforeUnits := datum.Units -// datum.Normalize(dataNormalizer.New()) -// afterVal := datum.Value -// afterUnits := datum.Units -// if *beforeVal != *afterVal { -// set["value"] = afterVal -// } -// if *beforeUnits != *afterUnits { -// set["units"] = afterUnits -// } -// identityFields, err = datum.IdentityFields() -// if err != nil { -// return datumID, nil, err -// } -// case ketone.Type: -// var datum ketone.Ketone -// dataBytes, err := bson.Marshal(bsonData) -// if err != nil { -// return datumID, nil, err -// } -// err = bson.Unmarshal(dataBytes, &datum) -// if err != nil { -// return datumID, nil, err -// } -// beforeVal := datum.Value -// beforeUnits := datum.Units -// datum.Normalize(dataNormalizer.New()) -// afterVal := datum.Value -// afterUnits := datum.Units -// if *beforeVal != *afterVal { -// set["value"] = afterVal -// } -// if *beforeUnits != *afterUnits { -// set["units"] = afterUnits -// } -// identityFields, err = datum.IdentityFields() -// if err != nil { -// return datumID, nil, err -// } -// case continuous.Type: -// var datum continuous.Continuous -// dataBytes, err := bson.Marshal(bsonData) -// if err != nil { -// return datumID, nil, err -// } -// err = bson.Unmarshal(dataBytes, &datum) -// if err != nil { -// return datumID, nil, err -// } -// // NOTE: applies to any type that has a `Glucose` property -// // we need to normalise so that we can get the correct `Units`` and `Value`` precsion that we would if ingested via the platform. -// // as these are both being used in the hash calc via the IdentityFields we want to persist these changes if they are infact updated. -// beforeVal := datum.Value -// beforeUnits := datum.Units -// datum.Normalize(dataNormalizer.New()) -// afterVal := datum.Value -// afterUnits := datum.Units -// if *beforeVal != *afterVal { -// set["value"] = afterVal -// } -// if *beforeUnits != *afterUnits { -// set["units"] = afterUnits -// } -// identityFields, err = datum.IdentityFields() -// if err != nil { -// return datumID, nil, err -// } -// default: -// var datum types.Base -// dataBytes, err := bson.Marshal(bsonData) -// if err != nil { -// return datumID, nil, err -// } -// err = bson.Unmarshal(dataBytes, &datum) -// if err != nil { -// return datumID, nil, err -// } -// identityFields, err = datum.IdentityFields() -// if err != nil { -// return datumID, nil, err -// } -// } - -// hash, err := deduplicator.GenerateIdentityHash(identityFields) -// if err != nil { -// return datumID, nil, err -// } - -// set["_deduplicator"] = bson.M{"hash": hash} - -// updates = append(updates, bson.M{"$set": set}) -// if rename != nil { -// log.Printf("rename %v", rename) -// updates = append(updates, bson.M{"$rename": rename}) -// } -// if len(updates) != 1 { -// log.Printf("datum updates %d", len(updates)) -// } -// return datumID, updates, nil -// } From fa9d7b99bb6a03bd17b5d50838677f349e295814 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 15 Feb 2024 15:15:57 +1300 Subject: [PATCH 221/413] json formatting for errors --- .../utils/migrationUtil.go | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 883c490129..94ac4728aa 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -76,6 +76,7 @@ type MigrationUtil interface { Initialize(ctx context.Context, dataC *mongo.Collection) error Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func() bool) error OnError(data ErrorData) + SetUpdate(update Update) SetUpdates(update ...*mongo.UpdateOneModel) SetLastProcessed(lastID string) SetFetched(raw []bson.M) @@ -159,6 +160,10 @@ func (m *migrationUtil) SetUpdates(update ...*mongo.UpdateOneModel) { } } +func (m *migrationUtil) SetUpdate(update Update) { + m.dataUpdates = append(m.dataUpdates, update) +} + func (m *migrationUtil) SetLastProcessed(lastID string) { m.lastUpdatedId = lastID } @@ -176,12 +181,6 @@ func (m *migrationUtil) writeErrors(groupLimit *int) { if group != "" { logName = fmt.Sprintf("logs/error_%s_%s.log", group, timestamp) } - errorsJSON, err := json.MarshalIndent(errors, "", " ") - if err != nil { - log.Println(err) - os.Exit(1) - } - f, err := os.OpenFile(logName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { @@ -189,7 +188,15 @@ func (m *migrationUtil) writeErrors(groupLimit *int) { os.Exit(1) } defer f.Close() - f.WriteString(string(errorsJSON)) + + for _, data := range errors { + errorJSON, err := json.Marshal(data) + if err != nil { + log.Println(err) + os.Exit(1) + } + f.WriteString(string(errorJSON)) + } m.groupedErrors[group] = []ErrorData{} } } From 86087d5424498daaf25afa0937017a95e1f84b6e Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 15 Feb 2024 17:24:32 +1300 Subject: [PATCH 222/413] generate ans set hash --- .../utils/utils.go | 35 ++++++++++--------- .../utils/utils_test.go | 2 -- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 5e735e9956..dac6906dce 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -14,6 +14,7 @@ import ( "github.com/tidepool-org/platform/data" "github.com/tidepool-org/platform/data/blood/glucose" + "github.com/tidepool-org/platform/data/deduplicator/deduplicator" dataNormalizer "github.com/tidepool-org/platform/data/normalizer" "github.com/tidepool-org/platform/data/types/basal" "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" @@ -30,6 +31,7 @@ import ( "github.com/tidepool-org/platform/data/types/settings/pump" errorsP "github.com/tidepool-org/platform/errors" "github.com/tidepool-org/platform/metadata" + "github.com/tidepool-org/platform/pointer" structureParser "github.com/tidepool-org/platform/structure/parser" structureValidator "github.com/tidepool-org/platform/structure/validator" ) @@ -175,6 +177,8 @@ func BuildPlatformDatum(objID string, objType string, objectData map[string]inte datum := dataTypesFactory.ParseDatum(parser) if datum != nil && *datum != nil { + (*datum).SetUserID(parser.String("_userId")) + (*datum).SetCreatedTime(parser.Time("createdTime", time.RFC3339Nano)) (*datum).Validate(validator) (*datum).Normalize(normalizer) } else { @@ -185,14 +189,12 @@ func BuildPlatformDatum(objID string, objType string, objectData map[string]inte validator.String("_archivedTime", parser.String("_archivedTime")) validator.String("_groupId", parser.String("_groupId")).Exists() validator.String("_id", parser.String("_id")).Exists() - validator.String("_userId", parser.String("_userId")).Exists() validator.Int("_version", parser.Int("_version")).Exists() validator.Int("_schemaVersion", parser.Int("_schemaVersion")) validator.Object("_deduplicator", parser.Object("_deduplicator")) validator.String("uploadId", parser.String("uploadId")).Exists() validator.String("guid", parser.String("guid")) - validator.Time("createdTime", parser.Time("createdTime", time.RFC3339Nano)).Exists() validator.Time("modifiedTime", parser.Time("modifiedTime", time.RFC3339Nano)) validator.Time("localTime", parser.Time("localTime", time.RFC3339Nano)) @@ -229,24 +231,23 @@ func BuildPlatformDatum(objID string, objType string, objectData map[string]inte return nil, err } - // TODO set the hash - // fields, err := (*datum).IdentityFields() - // if err != nil { - // return nil, errorsP.Wrap(err, "unable to gather identity fields for datum") - // } + fields, err := (*datum).IdentityFields() + if err != nil { + return nil, errorsP.Wrap(err, "unable to gather identity fields for datum") + } - // hash, err := deduplicator.GenerateIdentityHash(fields) - // if err != nil { - // return nil, errorsP.Wrap(err, "unable to generate identity hash for datum") - // } + hash, err := deduplicator.GenerateIdentityHash(fields) + if err != nil { + return nil, errorsP.Wrap(err, "unable to generate identity hash for datum") + } - // deduplicator := (*datum).DeduplicatorDescriptor() - // if deduplicator == nil { - // deduplicator = data.NewDeduplicatorDescriptor() - // } - // deduplicator.Hash = pointer.FromString(hash) + deduplicator := (*datum).DeduplicatorDescriptor() + if deduplicator == nil { + deduplicator = data.NewDeduplicatorDescriptor() + } + deduplicator.Hash = pointer.FromString(hash) - // (*datum).SetDeduplicatorDescriptor(deduplicator) + (*datum).SetDeduplicatorDescriptor(deduplicator) return datum, nil } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 9d4991aec9..d134a94695 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -72,7 +72,6 @@ var _ = Describe("back-37", func() { Expect(datum).ToNot(BeNil()) Expect((*datum).GetType()).To(Equal(continuous.Type)) }) - It("should successfully build carelink pump settings", func() { pSettingsData, err := setup(test.PumpSettingsCarelink) Expect(err).To(BeNil()) @@ -106,7 +105,6 @@ var _ = Describe("back-37", func() { Expect(datum).ToNot(BeNil()) Expect((*datum).GetType()).To(Equal(calculator.Type)) }) - It("should successfully build device event", func() { deviceEventData, err := setup(test.ReservoirChange) Expect(err).To(BeNil()) From ca18a36b14ac45863b2ca7ae39898f6a7e504e74 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 15 Feb 2024 17:26:29 +1300 Subject: [PATCH 223/413] new line after each --- migrations/20231128_jellyfish_migration/utils/migrationUtil.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 94ac4728aa..d57a266044 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -195,7 +195,7 @@ func (m *migrationUtil) writeErrors(groupLimit *int) { log.Println(err) os.Exit(1) } - f.WriteString(string(errorJSON)) + f.WriteString(string(errorJSON) + "\n") } m.groupedErrors[group] = []ErrorData{} } From db165bdd90fe7da426286d1d4c4cfeae40861eb4 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 21 Feb 2024 09:43:55 +1300 Subject: [PATCH 224/413] all tests --- migrations/20231128_jellyfish_migration/utils/test/data.go | 1 + migrations/20231128_jellyfish_migration/utils/utils.go | 5 ++++- migrations/20231128_jellyfish_migration/utils/utils_test.go | 3 --- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go index 142a051923..354460d0a1 100644 --- a/migrations/20231128_jellyfish_migration/utils/test/data.go +++ b/migrations/20231128_jellyfish_migration/utils/test/data.go @@ -185,6 +185,7 @@ func tandemWizardDatum() map[string]interface{} { "rate": 0.7, } + datum["units"] = "mmol/L" datum["duration"] = 300000 datum["rate"] = 0.335 datum["percent"] = 0.47857142857142865 diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index dac6906dce..d241458d00 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -215,6 +215,10 @@ func BuildPlatformDatum(objID string, objType string, objectData map[string]inte validator.String("previousOverride", parser.String("previousOverride")) validator.Int("index", parser.Int("index")) validator.String("statusId", parser.String("statusId")) + case calculator.Type: + validator.Float64("percent", parser.Float64("percent")) + validator.Float64("rate", parser.Float64("rate")) + validator.Int("duration", parser.Int("duration")) } parser.NotParsed() @@ -269,7 +273,6 @@ func GetDatumChanges(id string, datum interface{}, original map[string]interface notRequired := []string{ "_active", "_archivedTime", - "_deduplicator", "_groupId", "_id", "_schemaVersion", diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index d134a94695..93553ec619 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -97,7 +97,6 @@ var _ = Describe("back-37", func() { Expect((*datum).GetType()).To(Equal(pump.Type)) }) It("should successfully build tandem wizard", func() { - Skip("todo sort out /duration, /percent and /rate") calcData, err := setup(test.WizardTandem) Expect(err).To(BeNil()) datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", calcData["_id"]), calculator.Type, calcData) @@ -113,7 +112,6 @@ var _ = Describe("back-37", func() { Expect(datum).ToNot(BeNil()) Expect((*datum).GetType()).To(Equal(device.Type)) }) - It("should successfully build cgm settings", func() { deviceEventData, err := setup(test.CGMSetting) Expect(err).To(BeNil()) @@ -122,7 +120,6 @@ var _ = Describe("back-37", func() { Expect(datum).ToNot(BeNil()) Expect((*datum).GetType()).To(Equal(cgm.Type)) }) - }) var _ = Describe("ApplyBaseChanges", func() { From 03aaf809710e67481a6f2c36729e8abb018405d4 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 21 Feb 2024 11:48:28 +1300 Subject: [PATCH 225/413] output diff in batches also --- .../jellyfish_migration.go | 3 +- .../20231128_jellyfish_migration/tst.json | 1984 ----------------- .../utils/migrationUtil.go | 57 +- .../utils/utils.go | 25 +- .../utils/utils_test.go | 8 +- 5 files changed, 46 insertions(+), 2031 deletions(-) delete mode 100644 migrations/20231128_jellyfish_migration/tst.json diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 0027e96339..f29692d170 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -232,7 +232,7 @@ func (m *Migration) fetchAndProcess() bool { } itemID := fmt.Sprintf("%v", item["_id"]) itemType := fmt.Sprintf("%v", item["type"]) - updates, err := utils.ProcessDatum(itemID, itemType, item, m.config.audit) + updates, err := utils.ProcessDatum(itemID, itemType, item) if err != nil { m.migrationUtil.OnError(utils.ErrorData{Error: err, ItemID: itemID, ItemType: itemType}) } @@ -248,7 +248,6 @@ func (m *Migration) fetchAndProcess() bool { all = append(all, item) } m.migrationUtil.SetFetched(all) - //should we write errors here as intermediate step? return len(all) > 0 } return false diff --git a/migrations/20231128_jellyfish_migration/tst.json b/migrations/20231128_jellyfish_migration/tst.json deleted file mode 100644 index 97592ea631..0000000000 --- a/migrations/20231128_jellyfish_migration/tst.json +++ /dev/null @@ -1,1984 +0,0 @@ -[ - { - "_id": "003pv66tbv4ts0d7dtg87iqgfue2njko", - "diff": [ - { - "$set": { - "bgTarget": { "0": { "low": 0.24649 } }, - "insulinSensitivity": { "3": { "amount": 0.10784 } }, - "units": { "bg": "mmol/L" } - } - } - ] - }, - { - "_id": "003q3akh725mgom2o0veto788r3omfl1", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "004em6c9cjnblofd4mo2kcqg9tlsamec", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "004em6c9cjnblofd4mo2kcqg9tlsamec_0", - "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] - }, - { - "_id": "004mpfpguo8imiijdd72i6ik7d375rq9", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00555ome25877chsjcpfecenmven56ir", - "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] - }, - { - "_id": "0056goqpstl5blnvu4j5ruthmh0ve8lm", - "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] - }, - { - "_id": "0056goqpstl5blnvu4j5ruthmh0ve8lm_0", - "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] - }, - { - "_id": "005hc13gfoq5fv6daph9is1qi5p2qfin", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "005hc13gfoq5fv6daph9is1qi5p2qfin_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00668njtmootganjsu2ulhas9q76npr8", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "006nc3tg0affjbpp9epn2e7oujsl2eoq", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "006nc3tg0affjbpp9epn2e7oujsl2eoq_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "007eslnt672r7irnnp5ri517n64kb0o0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "007eslnt672r7irnnp5ri517n64kb0o0_0", - "diff": [{ "$unset": { "suppressed": { "clockDriftOffset": "" } } }] - }, - { - "_id": "008fps2ork9n3731otmh7m25rjb125ds", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "008fps2ork9n3731otmh7m25rjb125ds_0", - "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] - }, - { - "_id": "008gh26sbih90urq5pgrv6qslhfssqeb", - "diff": [ - { "$unset": { "suppressed": { "suppressed": { "timezoneOffset": "" } } } } - ] - }, - { - "_id": "008gh26sbih90urq5pgrv6qslhfssqeb_0", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "008up7g8cfoid7seogp30dod11clotne", - "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] - }, - { - "_id": "008up7g8cfoid7seogp30dod11clotne_0", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "0090h2apbmd9sc17i3ahl0tdtomadkf8", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "0090h2apbmd9sc17i3ahl0tdtomadkf8_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00941bse1rusk3oir9m2c3gg5i51m9eo", - "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] - }, - { - "_id": "00941bse1rusk3oir9m2c3gg5i51m9eo_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "009fbg2kclihtpfj08mhu9ubdro0fj9d", - "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] - }, - { - "_id": "009fbg2kclihtpfj08mhu9ubdro0fj9d_0", - "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] - }, - { - "_id": "00a7rvhhn17u23hogcob4cu0bfr2mbnk", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "00a7rvhhn17u23hogcob4cu0bfr2mbnk_0", - "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] - }, - { - "_id": "00a9egu2esitblp23n4alk92re21hqad", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "00a9egu2esitblp23n4alk92re21hqad_0", - "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] - }, - { - "_id": "00ak731q2gbn6m436dmu6e78u80jm5v9", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00amphcpherhqco8erolvoj5uf07od4a", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00amphcpherhqco8erolvoj5uf07od4a_0", - "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] - }, - { - "_id": "00banp948lntevb74c9mnus6qoqutgsl", - "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] - }, - { - "_id": "00banp948lntevb74c9mnus6qoqutgsl_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00bhgfrumqssh38i8pia3ti30gfgctcs", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00bnlg7mbpfjvmg4orvdd3783g11s88a", - "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] - }, - { - "_id": "00bnlg7mbpfjvmg4orvdd3783g11s88a_0", - "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] - }, - { - "_id": "00bsjoiu7elkq7tahcspl1apl86f4tql", - "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] - }, - { - "_id": "00bsjoiu7elkq7tahcspl1apl86f4tql_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00c8hsa1d72ns99uv496bsr1lb337n83", - "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] - }, - { - "_id": "00c8hsa1d72ns99uv496bsr1lb337n83_0", - "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] - }, - { - "_id": "00c8jq6crun5762qsl0t5hfkau42utib", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00dcc5rrpur7ppahjrdpse04t66c6ou6", - "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] - }, - { - "_id": "00dcc5rrpur7ppahjrdpse04t66c6ou6_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00ddv5fr5q4hg33253rvd9ajoa4cmtqd", - "diff": [{ "$unset": { "suppressed": { "source": "" } } }] - }, - { - "_id": "00ddv5fr5q4hg33253rvd9ajoa4cmtqd_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00e2eeq17vn9bmsftk3ls7b3t6aibpch", - "diff": [{ "$unset": { "suppressed": { "index": "" } } }] - }, - { - "_id": "00e2eeq17vn9bmsftk3ls7b3t6aibpch_0", - "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] - }, - { - "_id": "00ef5rntkfhr4vql89cvbjkul7qeffv6", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00ekb6v217ugr0ohcsi0qhfq3roq56p1", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00fcpm9tbv1lgmpo7sjehk55v222f1ln", - "diff": [ - { - "$set": { - "rateOfChangeAlert": { - "fallRate": { "enabled": false, "rate": -0.16652243973136602 }, - "riseRate": { "enabled": false, "rate": 0.16652243973136602 } - } - } - }, - { "$unset": { "rateOfChangeAlerts": "" } } - ] - }, - { - "_id": "00fdte897t1h2a8kehh54lh0kui1rsku", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00fopd2svgrq295hg8hjbc5g1640mr2e", - "diff": [ - { - "$set": { - "rateOfChangeAlert": { - "fallRate": { "enabled": true, "rate": -0.16652243973136602 }, - "riseRate": { "enabled": false, "rate": 0.16652243973136602 } - } - } - }, - { "$unset": { "rateOfChangeAlerts": "" } } - ] - }, - { - "_id": "00fshp28i8i1rsfmmvghtb3esoco1pov", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00ftthnoc3m08bjd7f5nuthbktkg119d", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00gri8pvjp8a04erp9agtf9cisb632c2", - "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] - }, - { - "_id": "00gri8pvjp8a04erp9agtf9cisb632c2_0", - "diff": [{ "$unset": { "suppressed": { "clockDriftOffset": "" } } }] - }, - { - "_id": "00h97gipch5r5vek1pb40i9uljrb01ua", - "diff": [ - { - "$set": { - "bgTargets": { "Test1": { "15": 0.36973 } }, - "insulinSensitivities": { "Test1": { "15": 0.33892 } }, - "units": { "bg": "mmol/L" } - } - } - ] - }, - { - "_id": "00hl61lmuje16gko3rvdfdr0sp4qs6ol", - "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] - }, - { - "_id": "00hl61lmuje16gko3rvdfdr0sp4qs6ol_0", - "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] - }, - { - "_id": "00hqa1a9c3cpdcch5d6h7vcos6krh0ce", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00ht555qvki7cbk674v6cm26h2312j61", - "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] - }, - { - "_id": "00ht555qvki7cbk674v6cm26h2312j61_0", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "00i2mohjo2mo2s2kom6hnqrb4f64jshr", - "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] - }, - { - "_id": "00i2mohjo2mo2s2kom6hnqrb4f64jshr_0", - "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] - }, - { - "_id": "00iqofhuol103ba49jalb4h82djkk0o0", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00j6nvem3qr8b67olqv3ii9801t0astn", - "diff": [{ "$unset": { "suppressed": { "source": "" } } }] - }, - { - "_id": "00j6nvem3qr8b67olqv3ii9801t0astn_0", - "diff": [{ "$unset": { "suppressed": { "index": "" } } }] - }, - { - "_id": "00j9eo5f5nh3ien4h4u8ovlrdu46c95n", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "00j9eo5f5nh3ien4h4u8ovlrdu46c95n_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00j9rqcumsqq2sg8832dveg3ido6k0cb", - "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] - }, - { - "_id": "00j9rqcumsqq2sg8832dveg3ido6k0cb_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00jtrn77rnvip9fk855pm8v793esshe8", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00k0vhhfv20b9id8iamhvhcldm7nmg5e", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00krmkvdi13ioii2s4j06jkjq3snos2i", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00ld99qpavd0q36seo86s5clp11jeavd", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00ld99qpavd0q36seo86s5clp11jeavd_0", - "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] - }, - { - "_id": "00m3d1b7m7f72oj4e2p09qtverpui4be", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00mfmt0kohnisnb3giudr05uik0egqmm", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00mfmt0kohnisnb3giudr05uik0egqmm_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00ms1frj45tg7o61a3u84qcpr9nhtmvs", - "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] - }, - { - "_id": "00ms1frj45tg7o61a3u84qcpr9nhtmvs_0", - "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] - }, - { - "_id": "00mvdtkn892cqissvttno8k55t2d0sj5", - "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] - }, - { - "_id": "00n9aks33iug7ri7h2dimh495ub85e74", - "diff": [{ "$unset": { "suppressed": { "clockDriftOffset": "" } } }] - }, - { - "_id": "00n9aks33iug7ri7h2dimh495ub85e74_0", - "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] - }, - { - "_id": "00nqj9ckkvach91pj4e3krsc6ea2guk9", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00obfp50c3kog4kq28ln4ea9tc2pkf7t", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "00obfp50c3kog4kq28ln4ea9tc2pkf7t_0", - "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] - }, - { - "_id": "00oufbhdambbqdlavk39maf4i227hbf8", - "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] - }, - { - "_id": "00oufbhdambbqdlavk39maf4i227hbf8_0", - "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] - }, - { - "_id": "00p3v8dr9qlscvopuhvgk96g7ab6nmd8", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00p3v8dr9qlscvopuhvgk96g7ab6nmd8_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "003pv66tbv4ts0d7dtg87iqgfue2njko", - "diff": [ - { - "$set": { - "bgTarget": { "0": { "low": 0.24649 } }, - "insulinSensitivity": { "3": { "amount": 0.10784 } }, - "units": { "bg": "mmol/L" } - } - } - ] - }, - { - "_id": "003q3akh725mgom2o0veto788r3omfl1", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "004em6c9cjnblofd4mo2kcqg9tlsamec", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "004em6c9cjnblofd4mo2kcqg9tlsamec_0", - "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] - }, - { - "_id": "004mpfpguo8imiijdd72i6ik7d375rq9", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00555ome25877chsjcpfecenmven56ir", - "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] - }, - { - "_id": "0056goqpstl5blnvu4j5ruthmh0ve8lm", - "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] - }, - { - "_id": "0056goqpstl5blnvu4j5ruthmh0ve8lm_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "005hc13gfoq5fv6daph9is1qi5p2qfin", - "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] - }, - { - "_id": "005hc13gfoq5fv6daph9is1qi5p2qfin_0", - "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] - }, - { - "_id": "00668njtmootganjsu2ulhas9q76npr8", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "006nc3tg0affjbpp9epn2e7oujsl2eoq", - "diff": [{ "$unset": { "suppressed": { "clockDriftOffset": "" } } }] - }, - { - "_id": "006nc3tg0affjbpp9epn2e7oujsl2eoq_0", - "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] - }, - { - "_id": "007eslnt672r7irnnp5ri517n64kb0o0", - "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] - }, - { - "_id": "007eslnt672r7irnnp5ri517n64kb0o0_0", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "008fps2ork9n3731otmh7m25rjb125ds", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "008fps2ork9n3731otmh7m25rjb125ds_0", - "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] - }, - { - "_id": "008gh26sbih90urq5pgrv6qslhfssqeb", - "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] - }, - { - "_id": "008gh26sbih90urq5pgrv6qslhfssqeb_0", - "diff": [{ "$unset": { "suppressed": { "source": "" } } }] - }, - { - "_id": "008up7g8cfoid7seogp30dod11clotne", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "008up7g8cfoid7seogp30dod11clotne_0", - "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] - }, - { - "_id": "0090h2apbmd9sc17i3ahl0tdtomadkf8", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "0090h2apbmd9sc17i3ahl0tdtomadkf8_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00941bse1rusk3oir9m2c3gg5i51m9eo", - "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] - }, - { - "_id": "00941bse1rusk3oir9m2c3gg5i51m9eo_0", - "diff": [{ "$unset": { "suppressed": { "clockDriftOffset": "" } } }] - }, - { - "_id": "009fbg2kclihtpfj08mhu9ubdro0fj9d", - "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] - }, - { - "_id": "009fbg2kclihtpfj08mhu9ubdro0fj9d_0", - "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] - }, - { - "_id": "00a7rvhhn17u23hogcob4cu0bfr2mbnk", - "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] - }, - { - "_id": "00a7rvhhn17u23hogcob4cu0bfr2mbnk_0", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "00a9egu2esitblp23n4alk92re21hqad", - "diff": [{ "$unset": { "suppressed": { "index": "" } } }] - }, - { - "_id": "00a9egu2esitblp23n4alk92re21hqad_0", - "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] - }, - { - "_id": "00ak731q2gbn6m436dmu6e78u80jm5v9", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00amphcpherhqco8erolvoj5uf07od4a", - "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] - }, - { - "_id": "00amphcpherhqco8erolvoj5uf07od4a_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00banp948lntevb74c9mnus6qoqutgsl", - "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] - }, - { - "_id": "00banp948lntevb74c9mnus6qoqutgsl_0", - "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] - }, - { - "_id": "00bhgfrumqssh38i8pia3ti30gfgctcs", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00bnlg7mbpfjvmg4orvdd3783g11s88a", - "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] - }, - { - "_id": "00bnlg7mbpfjvmg4orvdd3783g11s88a_0", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "00bsjoiu7elkq7tahcspl1apl86f4tql", - "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] - }, - { - "_id": "00bsjoiu7elkq7tahcspl1apl86f4tql_0", - "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] - }, - { - "_id": "00c8hsa1d72ns99uv496bsr1lb337n83", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "00c8hsa1d72ns99uv496bsr1lb337n83_0", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "00c8jq6crun5762qsl0t5hfkau42utib", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00dcc5rrpur7ppahjrdpse04t66c6ou6", - "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] - }, - { - "_id": "00dcc5rrpur7ppahjrdpse04t66c6ou6_0", - "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] - }, - { - "_id": "00ddv5fr5q4hg33253rvd9ajoa4cmtqd", - "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] - }, - { - "_id": "00ddv5fr5q4hg33253rvd9ajoa4cmtqd_0", - "diff": [{ "$unset": { "suppressed": { "clockDriftOffset": "" } } }] - }, - { - "_id": "00e2eeq17vn9bmsftk3ls7b3t6aibpch", - "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] - }, - { - "_id": "00e2eeq17vn9bmsftk3ls7b3t6aibpch_0", - "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] - }, - { - "_id": "00ef5rntkfhr4vql89cvbjkul7qeffv6", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00ekb6v217ugr0ohcsi0qhfq3roq56p1", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00fcpm9tbv1lgmpo7sjehk55v222f1ln", - "diff": [ - { - "$set": { - "rateOfChangeAlert": { - "fallRate": { "enabled": false, "rate": -0.16652243973136602 }, - "riseRate": { "enabled": false, "rate": 0.16652243973136602 } - } - } - }, - { "$unset": { "rateOfChangeAlerts": "" } } - ] - }, - { - "_id": "00fdte897t1h2a8kehh54lh0kui1rsku", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00fopd2svgrq295hg8hjbc5g1640mr2e", - "diff": [ - { - "$set": { - "rateOfChangeAlert": { - "fallRate": { "enabled": true, "rate": -0.16652243973136602 }, - "riseRate": { "enabled": false, "rate": 0.16652243973136602 } - } - } - }, - { "$unset": { "rateOfChangeAlerts": "" } } - ] - }, - { - "_id": "00fshp28i8i1rsfmmvghtb3esoco1pov", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00ftthnoc3m08bjd7f5nuthbktkg119d", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00gri8pvjp8a04erp9agtf9cisb632c2", - "diff": [{ "$unset": { "suppressed": { "source": "" } } }] - }, - { - "_id": "00gri8pvjp8a04erp9agtf9cisb632c2_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00h97gipch5r5vek1pb40i9uljrb01ua", - "diff": [ - { - "$set": { - "bgTargets": { "Test": { "14": 0.2773 } }, - "insulinSensitivities": { "Test1": { "15": 0.33892 } }, - "units": { "bg": "mmol/L" } - } - } - ] - }, - { - "_id": "00hl61lmuje16gko3rvdfdr0sp4qs6ol", - "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] - }, - { - "_id": "00hl61lmuje16gko3rvdfdr0sp4qs6ol_0", - "diff": [{ "$unset": { "suppressed": { "source": "" } } }] - }, - { - "_id": "00hqa1a9c3cpdcch5d6h7vcos6krh0ce", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00ht555qvki7cbk674v6cm26h2312j61", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00ht555qvki7cbk674v6cm26h2312j61_0", - "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] - }, - { - "_id": "00i2mohjo2mo2s2kom6hnqrb4f64jshr", - "diff": [{ "$unset": { "suppressed": { "index": "" } } }] - }, - { - "_id": "00i2mohjo2mo2s2kom6hnqrb4f64jshr_0", - "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] - }, - { - "_id": "00iqofhuol103ba49jalb4h82djkk0o0", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00j6nvem3qr8b67olqv3ii9801t0astn", - "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] - }, - { - "_id": "00j6nvem3qr8b67olqv3ii9801t0astn_0", - "diff": [{ "$unset": { "suppressed": { "source": "" } } }] - }, - { - "_id": "00j9eo5f5nh3ien4h4u8ovlrdu46c95n", - "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] - }, - { - "_id": "00j9eo5f5nh3ien4h4u8ovlrdu46c95n_0", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "00j9rqcumsqq2sg8832dveg3ido6k0cb", - "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] - }, - { - "_id": "00j9rqcumsqq2sg8832dveg3ido6k0cb_0", - "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] - }, - { - "_id": "00jtrn77rnvip9fk855pm8v793esshe8", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00k0vhhfv20b9id8iamhvhcldm7nmg5e", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00krmkvdi13ioii2s4j06jkjq3snos2i", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00ld99qpavd0q36seo86s5clp11jeavd", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "00ld99qpavd0q36seo86s5clp11jeavd_0", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "00m3d1b7m7f72oj4e2p09qtverpui4be", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00mfmt0kohnisnb3giudr05uik0egqmm", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00mfmt0kohnisnb3giudr05uik0egqmm_0", - "diff": [{ "$unset": { "suppressed": { "source": "" } } }] - }, - { - "_id": "00ms1frj45tg7o61a3u84qcpr9nhtmvs", - "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] - }, - { - "_id": "00ms1frj45tg7o61a3u84qcpr9nhtmvs_0", - "diff": [{ "$unset": { "suppressed": { "clockDriftOffset": "" } } }] - }, - { - "_id": "00mvdtkn892cqissvttno8k55t2d0sj5", - "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] - }, - { - "_id": "00n9aks33iug7ri7h2dimh495ub85e74", - "diff": [{ "$unset": { "suppressed": { "index": "" } } }] - }, - { - "_id": "00n9aks33iug7ri7h2dimh495ub85e74_0", - "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] - }, - { - "_id": "00nqj9ckkvach91pj4e3krsc6ea2guk9", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00obfp50c3kog4kq28ln4ea9tc2pkf7t", - "diff": [{ "$unset": { "suppressed": { "source": "" } } }] - }, - { - "_id": "00obfp50c3kog4kq28ln4ea9tc2pkf7t_0", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "00oufbhdambbqdlavk39maf4i227hbf8", - "diff": [{ "$unset": { "suppressed": { "source": "" } } }] - }, - { - "_id": "00oufbhdambbqdlavk39maf4i227hbf8_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00p3v8dr9qlscvopuhvgk96g7ab6nmd8", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00p3v8dr9qlscvopuhvgk96g7ab6nmd8_0", - "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] - }, - { - "_id": "003pv66tbv4ts0d7dtg87iqgfue2njko", - "diff": [ - { - "$set": { - "bgTarget": { "0": { "low": 0.24649 } }, - "insulinSensitivity": { "3": { "amount": 0.10784 } }, - "units": { "bg": "mmol/L" } - } - } - ] - }, - { - "_id": "003q3akh725mgom2o0veto788r3omfl1", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "003ra7lle4afbui5b8u3jidrs185toua", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "003tcon8tounj2qm8k1v9h5l6pbjqa3b", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "003tosu2cr1vktgaepkromj2i97ld4jk", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0040ubuoala10qr24oa9mvifpb4fl4hr", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0043bmh3l05iumq933vfc5593jg4cv9j", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0043el25dr30hrh0jr5dscnntp20ls60", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0043ql9fkrvkkoipudv8ajforvta9cbn", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00445uh1pj66f3leubc9r5sv09gdd49a", - "diff": [{ "$unset": { "subType": "" } }] - }, - { - "_id": "00466bjjo66c5tkjj2h0q8qgqqosd1jh", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0048m6q2vli52njdm708mhtm775acbuq", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004anqm480clp5a9o3e1rf48jkuqlomn", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004ci48809baufo99uljbdahjup558r4", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004em6c9cjnblofd4mo2kcqg9tlsamec", - "diff": [{ "$unset": { "suppressed": { "source": "" } } }] - }, - { - "_id": "004em6c9cjnblofd4mo2kcqg9tlsamec_0", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "004kh7k5t42k4ci06cmo9dkdnjfo6d9j", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004mpfpguo8imiijdd72i6ik7d375rq9", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "004or2n1c0e7l2qip119t0h3gtt1gpt8", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004pe2e6mjd0je3c6hulhbtm4ql1u0nu", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004pt4qies4j1fn3vjei18p9pkauadlu", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004qs07ruhovdab3af26eko42o4repp5", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004t10h76l4m7f1sdc08i8grb2tl3rt1", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004u2t4kvug6jm31h2pkauh5cg3ud1eb", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004u5jq5tvpd4doci5r5o14brel7u0h8", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004vh9omub24akemqvl2qoiosohk02ig", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00555ome25877chsjcpfecenmven56ir", - "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] - }, - { - "_id": "0056goqpstl5blnvu4j5ruthmh0ve8lm", - "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] - }, - { - "_id": "0056goqpstl5blnvu4j5ruthmh0ve8lm_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "005ce26eb8enbqki8s26lfcrese0eji0", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005d7s5s4isuv35jkqibknsodes9ee0q", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005f1u9eq431t3pecccs8n5u99p37pln", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005fc44ql8u7a9ol6f8tdu3s080dqhtp", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005ggbg3ov1odn9li2g58lkrbn3n4v5m", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005hc13gfoq5fv6daph9is1qi5p2qfin", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "005hc13gfoq5fv6daph9is1qi5p2qfin_0", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "005hj9ua01t6gohbejpg5933j8f1k95t", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005iuclbuba3mtfablgbep4967eoous1", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005jkgj5ckra1up98nolt2c5aaf84c89", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005l02s5mdlgrjegbpajcfqaps58kmqc", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005ljq54s0dqggh2u34oc3dmgej6eqp9", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005ner9db6rau554pr5hkaf56vpphpc5", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005pl16rcd4j8n67v2qg360289jtr0f9", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005ruorcd7r67ura02li9kub84gde52v", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005utsujnbab9ajinah7qp8m70gbondn", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00604qao66ec2sh9p922ua0lv6mfihmp", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0060tke9cuqbcdr2iijsvf82hp9o9v4j", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0062cmrelkeicsrl2lgifqsarqi6b7sb", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0062qd8meqaglivgc4eedpcr10momkdv", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0064vp6s8non1lbkpin8k4kg58dohban", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00668njtmootganjsu2ulhas9q76npr8", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "0067bk24kethveo4jtoiihvdg29kcg90", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0068hksr5t845221jsnrbsm3b5m0qkgo", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0068j9nvdm9h17rb9vghca4j6ucto1ih", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0068mqnq491slqks11nr69sf4a56l9i8", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "006ddgmmnndmsi0itrmjr9q2kd5aad4e", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "006dj5poqljkjqe70mbaua37hmt51uq1", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "006e4nullfmotjd1hh88hh5ji6pmcpru", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "006efkgs0hd157dsgjsq9ogm4o6d4559", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "006f1k73pnc936ljspcrap57v1v0lgf3", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "006fi3c3r07ecqj1vd4gj5q9ohaus4qa", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "006j49e1rt77r7j4v740tjhskqfvimkd", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "006l3kga1ckaada9b5asekpkf6bi6nq9", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "006l3rotk6jmtm50ociedbbg9201n8os", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "006l6ckiloj3c705krg64qu6fi9avdi2", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "006nc3tg0affjbpp9epn2e7oujsl2eoq", - "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] - }, - { - "_id": "006nc3tg0affjbpp9epn2e7oujsl2eoq_0", - "diff": [{ "$unset": { "suppressed": { "source": "" } } }] - }, - { - "_id": "006o8hvfctons14ei4gkjrj4auth84hc", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "006oio2dok49d6pg5q0c8tautr0c9fn7", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "006oouq2bu3rugdq3laa5c89639u0io4", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "006otlt26p25f9qp9ehogglcd0ed9l62", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "006v149utv948n22ium7m5p1cr6hha73", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "006vihufp0tb10g9gla20qbrf2edku9l", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0073t0edlm57btvbujtgg41n5u1bjssl", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0074fglsh754iumf7gojg583h6ojmhk5", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0075cs940t81r78prn37evn3ae0v3se5", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0077ksousf8nfon712op5ep1gt27oka9", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0078ggolc99q04nc6pu0ladf6s42bn0f", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0078qg3j9r3a4gci2352gtv343o4l6k2", - "diff": [{ "$unset": { "subType": "" } }] - }, - { - "_id": "0079f8qel1v4p25nmqa8d7plmjlck5cm", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "007a2sr588memfodmj6vmo3s373ku6vl", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "007btaong91i1aueuhqj3mkbdjfv6mot", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "007d5mjbogp70vjnr8t82b72afqcrucr", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "007eptebsgbdemqce1e7jl0fehc8vavj", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "007eslnt672r7irnnp5ri517n64kb0o0", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "007eslnt672r7irnnp5ri517n64kb0o0_0", - "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] - }, - { - "_id": "007fbejiiuac7t48850qmahe9v7ic4cu", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "007hr6trebge4atgf8tatgu4mlk6ihng", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "007j8br7jom1cqp4p28n7mj8qghop22i", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "007kq781j1hi9t7varptnt9tj4s3c3be", - "diff": [{ "$unset": { "subType": "" } }] - }, - { - "_id": "007mogjej2nn77h8rbe3ik8qsdgo35s2", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "007ns5rb6nh0to1mnsfdj95s9kpcn5nk", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "007pjf5soi3q94o5ba896f7vp21pqlua", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "007q94q0k1575bpgebuvr3j068fqrt86", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "007r3is1ovpb213evesvnt7m3s00h2oc", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "007tbfb52apnpp8gat4r6k98h3r6nv2q", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "007up7upgtkmekcgqdad79gq7kqi3kd3", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "007ursvpkc13oqr2edq40o1gbv7rub83", - "diff": [{ "$unset": { "percent": "", "suppressed": "" } }] - }, - { - "_id": "007vgno227aogieimi1pjjsp4p4occle", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0083mro6bi2nbq1jml2vv8df1mdcl9e0", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0084qsqgn50e8em83n995dkn3uh3ibiv", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00878olaqq67h1ik6mkbnpda324ea1la", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0089oe6giuouoma7h3lvt1cglqgtk45t", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "008aik63ll335f1qe1qe95mrl2g4e38n", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "008b9msfnsj1rv0jof8stimtr5f9g3bi", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "008bit1hos8a922i8g5iesag4kn2im8j", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "008fps2ork9n3731otmh7m25rjb125ds", - "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] - }, - { - "_id": "008fps2ork9n3731otmh7m25rjb125ds_0", - "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] - }, - { - "_id": "008gh26sbih90urq5pgrv6qslhfssqeb", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "008gh26sbih90urq5pgrv6qslhfssqeb_0", - "diff": [{ "$unset": { "suppressed": { "jsDate": "" } } }] - }, - { - "_id": "008hsg72golrt9or7lipgro2cbf5hhqs", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "008i9gvupisq21ahhpdmiui035guucft", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "008je41fp50fesgcadbg1lbgs5gffjmj", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "008kf497ovbne2tu6a3mqvdqo1nfk3ba", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "008lbeiebmu2eg1hegjkat438hao3ecf", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "008rjdiu7sfcr2sfeicfb85tk68bg8ru", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "008ru0ul1l0f5kpr7h17dg45e6fcpl33", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "008s9v9ff2g1kgj0q14suba8r8u78u3h", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "008smm94h1i0kk4rrgv867t3qr5i9gg8", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "008u3jukn7s6qo69128ibgd7p5pt8k3c", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "008up7g8cfoid7seogp30dod11clotne", - "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] - }, - { - "_id": "008up7g8cfoid7seogp30dod11clotne_0", - "diff": [{ "$unset": { "suppressed": { "source": "" } } }] - }, - { - "_id": "0090h2apbmd9sc17i3ahl0tdtomadkf8", - "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] - }, - { - "_id": "0090h2apbmd9sc17i3ahl0tdtomadkf8_0", - "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] - }, - { - "_id": "0091i3hqi6jb45cvqme2li497bsu4gh4", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0091i8pmns2oh2appbtvdn8vk2godiv6", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0092gdmqqp4rpi4tgjobv230msb892tj", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00937vrp363lds5i4o93iti8p4ubca5p", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00941bse1rusk3oir9m2c3gg5i51m9eo", - "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] - }, - { - "_id": "00941bse1rusk3oir9m2c3gg5i51m9eo_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "0095ak9reeakg58a9sdo5u16aq2gqsf5", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0099ahor7c9tcd8m56ojkje1upna41gh", - "diff": [{ "$unset": { "subType": "" } }] - }, - { - "_id": "0099b74qqipdrrqg1f93ph2akgultbbn", - "diff": [{ "$unset": { "subType": "" } }] - }, - { - "_id": "009anmftasc9kidp0d9ml10brci2c287", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "009d8prcaur90hfhcvp87drc3i7n3mki", - "diff": [{ "$unset": { "subType": "" } }] - }, - { - "_id": "009ec8ldt8o1nv2kd6v33q0b0193vlb9", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "009esdmj0eccmkkju6k22j5pqc4gc0b5", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "009fbg2kclihtpfj08mhu9ubdro0fj9d", - "diff": [{ "$unset": { "suppressed": { "clockDriftOffset": "" } } }] - }, - { - "_id": "009fbg2kclihtpfj08mhu9ubdro0fj9d_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "009fssgce80qm8k21987fha1v4p7eg90", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "009gdl0l7u22o9qi82g7iusb4ccs7ib3", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "009lltpsob1t75igi6d1iv52gqg79eb1", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "009ls6fhlknhno8dj6sjvp9u8b7kbvq0", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "009o1tb4dneejn1v2kb4helr1qg4meuc", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "009qrv528ujo2agbtk5ljb2irucd1lsu", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00a4umftr4kpc4bg8uidcjm7d8ugrrte", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00a6tc02ull7mniv8jevae0eru1dvure", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00a7rvhhn17u23hogcob4cu0bfr2mbnk", - "diff": [{ "$unset": { "suppressed": { "index": "" } } }] - }, - { - "_id": "00a7rvhhn17u23hogcob4cu0bfr2mbnk_0", - "diff": [{ "$unset": { "suppressed": { "index": "" } } }] - }, - { - "_id": "00a8196cn45kd29lk9rf1f4l92kg80mb", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00a9egu2esitblp23n4alk92re21hqad", - "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] - }, - { - "_id": "00a9egu2esitblp23n4alk92re21hqad_0", - "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] - }, - { - "_id": "00adlmer1m0d64htin9924b94soht9he", - "diff": [{ "$unset": { "subType": "" } }] - }, - { - "_id": "00aj562fmn4u2kn5m6uk058gkbf1g79n", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00ak731q2gbn6m436dmu6e78u80jm5v9", - "diff": [{ "$unset": { "suppressed": { "index": "" } } }] - }, - { - "_id": "00amnuknhl68eueg1lftjdesm3np4k8q", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00amphcpherhqco8erolvoj5uf07od4a", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "00amphcpherhqco8erolvoj5uf07od4a_0", - "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] - }, - { - "_id": "00ao0tb18adh4dnklqh1suluo616r5ok", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00apqsvgc7jm6ssklb5lgibon6m10es6", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00aqif8avfqsp2jusb36300g9vtg3fth", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00arkl43ougqpc1vt58frgdbbte4tkpg", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00as323dtasn45mptn7lul2sq01u30u0", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00avhj5oogglukh91fgt7bnmk7ea96ik", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00avjhsqnvnld64rcps7nbs1difvb4fn", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00avl0g9bjvk9oh0plfdm9dliahe1bgm", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00b0f5l0rmi5vgjfqs0i6rat9ldfmks6", - "diff": [{ "$unset": { "subType": "" } }] - }, - { - "_id": "00b2hji7pk7kfjvc8oa0o7na5nqfiajm", - "diff": [{ "$unset": { "subType": "" } }] - }, - { - "_id": "00b3go5mujmq45ijrl5slc4hrrpn90rl", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00b4u66tpsebnptps8al42lddnc22r21", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00b53fusv777nrncnl7dmv5oc64auic1", - "diff": [{ "$unset": { "subType": "" } }] - }, - { - "_id": "00b6l9pqvqs3fn1s55saj6plua0j6n43", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00b876cu0spuuoe7vs3kuvhodsmv8jbd", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00ba0s1tnf4bob1lmk2um8bdn430khr2", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00banp948lntevb74c9mnus6qoqutgsl", - "diff": [{ "$unset": { "suppressed": { "deviceId": "" } } }] - }, - { - "_id": "00banp948lntevb74c9mnus6qoqutgsl_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00bbnhfdl3hl92f2ucutb1iv2ug3ldm1", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00be4iinutpqbep1jr250krkheutbjlv", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00bgl9saknei3pqtdi9bt79e8cfarjnm", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00bhgfrumqssh38i8pia3ti30gfgctcs", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00bmfif6ju4uc38l5jmqjm9umv6tfsvd", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00bnlg7mbpfjvmg4orvdd3783g11s88a", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00bnlg7mbpfjvmg4orvdd3783g11s88a_0", - "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] - }, - { - "_id": "00bno9dug4u4ncus8522ese4i5v1qkeo", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00bnp0go651o085asv767ufijn6hu8ba", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00bobb7l6m0cnaua9k606ngu1kj3m8p8", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00brqbe948q5uomu382nk0ucgre6dij1", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00bsjoiu7elkq7tahcspl1apl86f4tql", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00bsjoiu7elkq7tahcspl1apl86f4tql_0", - "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] - }, - { - "_id": "00bsrlvtnr831lbsg9eui393iridhsh4", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00bsvgdd3d3aha5aes1usac41fu64svu", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00bu50k4pphqqqhcdgp3d8cvrjlsos2t", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00c26rb4pe8ttmccugpb476f7s1grsrc", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00c30aci3h3g0ue1st3p83ev7bo0f5c0", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00c6fie9s3pb6g84r9qnufv3aq067cso", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00c8864becupu8qi30s6l7bi6v0v9ja8", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00c8hsa1d72ns99uv496bsr1lb337n83", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00c8hsa1d72ns99uv496bsr1lb337n83_0", - "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] - }, - { - "_id": "00c8jq6crun5762qsl0t5hfkau42utib", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "00cfm2h86002cr06klqni7ajg7peaoah", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00ch2aieeca34l32jsmgkn05o78h1a6m", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00cjjov0uivatlqu7k41e3tgipcgif10", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00cm9ciiffd3h08t9fatpcdes594tlm7", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00cmc50gm0l4l4cpq5eshvp2oh7fuj51", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00cocsqjg2g2ruqu636uj25jie110sb6", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00csndpk8s58fl53hct5kea6hfb80i5q", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00ct63h045l0n5sepj8aecoqh2icapin", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00ctd03k7t25016opvvq8v18ng9p8s0q", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00d08clqba62glnv7fj0a9skvfl72rjf", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00d1l3qamhggiig1rf3mn35sh0ocgvt8", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00d2dq417dha4oin9j0mi0ge02nm8kq4", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00d3furp7tb1njokih8l0tt7qii0cvd3", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00d48k3nj3mrm2pe4e6pqitfp2smt4ec", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00d8ebcb4v3q2lfoj3o8qbh54shgchma", - "diff": [{ "$unset": { "subType": "" } }] - }, - { - "_id": "00d9l7o7040ifu6bf3biu7ai5cfjcfqd", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00dajc12l1l73nmblogeu157qtgvrmo2", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00dbqbdpo7hkhv3ea22cldf2jdlv9as3", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00dbu188uv4usi4jrjefucuj0qh8pjsv", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00dcc5rrpur7ppahjrdpse04t66c6ou6", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00dcc5rrpur7ppahjrdpse04t66c6ou6_0", - "diff": [{ "$unset": { "suppressed": { "payload": "" } } }] - }, - { - "_id": "00ddv5fr5q4hg33253rvd9ajoa4cmtqd", - "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] - }, - { - "_id": "00ddv5fr5q4hg33253rvd9ajoa4cmtqd_0", - "diff": [{ "$unset": { "suppressed": { "timezoneOffset": "" } } }] - }, - { - "_id": "00dfl9nk8fa2d5foumflond3tk7hubkm", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00div16jgar0fh9miuka93roj0tdsv5l", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00dla9ek59hqt5jt0hiot620m6ujie7e", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00dldk1orv44qvmqd4nu7hsj45826soe", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00dpoopkga7ei3rh78ob7sfns3vk9fnv", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00dropqr92dil3hhvvjft42qifal33mg", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00ds9u6nq3lbl3rufq3khtd5bt4qi65e", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00dt4kud9rd0redke43lrgf9d2g548fm", - "diff": [{ "$unset": { "subType": "" } }] - }, - { - "_id": "00dvb2j21n8fj00p7ndc48o585avt5mm", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00dvq539utrfpk82q2utfpqcchq0qtea", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00e0g189gc8rnif3sgi88ebr4p15a72e", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00e22qutjqlbojj7a2moa0pubr0ptbqv", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00e2eeq17vn9bmsftk3ls7b3t6aibpch", - "diff": [{ "$unset": { "suppressed": { "index": "" } } }] - }, - { - "_id": "00e2eeq17vn9bmsftk3ls7b3t6aibpch_0", - "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] - }, - { - "_id": "003pv66tbv4ts0d7dtg87iqgfue2njko", - "diff": [ - { - "$set": { - "bgTarget": { "0": { "low": 0.24649 } }, - "insulinSensitivity": { "3": { "amount": 0.10784 } }, - "units": { "bg": "mmol/L" } - } - } - ] - }, - { - "_id": "003q3akh725mgom2o0veto788r3omfl1", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "003ra7lle4afbui5b8u3jidrs185toua", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "003tcon8tounj2qm8k1v9h5l6pbjqa3b", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "003tosu2cr1vktgaepkromj2i97ld4jk", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0040ubuoala10qr24oa9mvifpb4fl4hr", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0043bmh3l05iumq933vfc5593jg4cv9j", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0043el25dr30hrh0jr5dscnntp20ls60", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0043ql9fkrvkkoipudv8ajforvta9cbn", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00445uh1pj66f3leubc9r5sv09gdd49a", - "diff": [{ "$unset": { "subType": "" } }] - }, - { - "_id": "00466bjjo66c5tkjj2h0q8qgqqosd1jh", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0048m6q2vli52njdm708mhtm775acbuq", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004anqm480clp5a9o3e1rf48jkuqlomn", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004ci48809baufo99uljbdahjup558r4", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004em6c9cjnblofd4mo2kcqg9tlsamec", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "004em6c9cjnblofd4mo2kcqg9tlsamec_0", - "diff": [{ "$unset": { "suppressed": { "deviceTime": "" } } }] - }, - { - "_id": "004kh7k5t42k4ci06cmo9dkdnjfo6d9j", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004mpfpguo8imiijdd72i6ik7d375rq9", - "diff": [{ "$unset": { "deliveryContext": "" } }] - }, - { - "_id": "004or2n1c0e7l2qip119t0h3gtt1gpt8", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004pe2e6mjd0je3c6hulhbtm4ql1u0nu", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004pt4qies4j1fn3vjei18p9pkauadlu", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004qs07ruhovdab3af26eko42o4repp5", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004t10h76l4m7f1sdc08i8grb2tl3rt1", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004u2t4kvug6jm31h2pkauh5cg3ud1eb", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004u5jq5tvpd4doci5r5o14brel7u0h8", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "004vh9omub24akemqvl2qoiosohk02ig", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00555ome25877chsjcpfecenmven56ir", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "0056goqpstl5blnvu4j5ruthmh0ve8lm", - "diff": [{ "$unset": { "suppressed": { "duration": "" } } }] - }, - { - "_id": "0056goqpstl5blnvu4j5ruthmh0ve8lm_0", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "005ce26eb8enbqki8s26lfcrese0eji0", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005d7s5s4isuv35jkqibknsodes9ee0q", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005f1u9eq431t3pecccs8n5u99p37pln", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005fc44ql8u7a9ol6f8tdu3s080dqhtp", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005ggbg3ov1odn9li2g58lkrbn3n4v5m", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005hc13gfoq5fv6daph9is1qi5p2qfin", - "diff": [{ "$unset": { "suppressed": { "conversionOffset": "" } } }] - }, - { - "_id": "005hc13gfoq5fv6daph9is1qi5p2qfin_0", - "diff": [{ "$unset": { "suppressed": { "time": "" } } }] - }, - { - "_id": "005hj9ua01t6gohbejpg5933j8f1k95t", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005iuclbuba3mtfablgbep4967eoous1", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005jkgj5ckra1up98nolt2c5aaf84c89", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005l02s5mdlgrjegbpajcfqaps58kmqc", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005ljq54s0dqggh2u34oc3dmgej6eqp9", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005ner9db6rau554pr5hkaf56vpphpc5", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005pl16rcd4j8n67v2qg360289jtr0f9", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005ruorcd7r67ura02li9kub84gde52v", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "005utsujnbab9ajinah7qp8m70gbondn", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "00604qao66ec2sh9p922ua0lv6mfihmp", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0060tke9cuqbcdr2iijsvf82hp9o9v4j", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0062cmrelkeicsrl2lgifqsarqi6b7sb", - "diff": [{ "$unset": { "percent": "" } }] - }, - { - "_id": "0062qd8meqaglivgc4eedpcr10momkdv", - "diff": [{ "$unset": { "percent": "" } }] - } -] diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index d57a266044..c9e6d22ccb 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -41,19 +41,19 @@ type migrationUtil struct { client *mongo.Client config *MigrationUtilConfig updates []mongo.WriteModel - dataUpdates []Update - groupedErrors groupedErrors - rawData []bson.M - errorsCount int - updatedCount int - lastUpdatedId string - startedAt time.Time + //dataUpdates []Update + groupedErrors groupedErrors + rawData []bson.M + errorsCount int + updatedCount int + lastUpdatedId string + startedAt time.Time } -type Update struct { - ItemID string `json:"_id"` - MongoWrites []mongo.WriteModel `json:"diff"` -} +// type Update struct { +// ItemID string `json:"_id"` +// MongoWrites []mongo.WriteModel `json:"diff"` +// } type ErrorData struct { Error error `json:"error"` @@ -76,7 +76,7 @@ type MigrationUtil interface { Initialize(ctx context.Context, dataC *mongo.Collection) error Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func() bool) error OnError(data ErrorData) - SetUpdate(update Update) + //SetUpdate(update Update) SetUpdates(update ...*mongo.UpdateOneModel) SetLastProcessed(lastID string) SetFetched(raw []bson.M) @@ -105,10 +105,10 @@ func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client, lastID updates: []mongo.WriteModel{}, rawData: []bson.M{}, groupedErrors: groupedErrors{}, - dataUpdates: []Update{}, - errorsCount: 0, - updatedCount: 0, - startedAt: time.Now(), + //dataUpdates: []Update{}, + errorsCount: 0, + updatedCount: 0, + startedAt: time.Now(), } if lastID != nil { m.lastUpdatedId = *lastID @@ -160,9 +160,9 @@ func (m *migrationUtil) SetUpdates(update ...*mongo.UpdateOneModel) { } } -func (m *migrationUtil) SetUpdate(update Update) { - m.dataUpdates = append(m.dataUpdates, update) -} +// func (m *migrationUtil) SetUpdate(update Update) { +// m.dataUpdates = append(m.dataUpdates, update) +// } func (m *migrationUtil) SetLastProcessed(lastID string) { m.lastUpdatedId = lastID @@ -201,6 +201,24 @@ func (m *migrationUtil) writeErrors(groupLimit *int) { } } +func (m *migrationUtil) writeDiff(updates []mongo.WriteModel, from int, to int) { + now := time.Now() + logName := fmt.Sprintf("updates/diff%s_%d-%d.log", now.Format(time.TimeOnly), from, to) + f, err := os.OpenFile(logName, + os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Println(err) + os.Exit(1) + } + defer f.Close() + diffJSON, err := json.Marshal(updates) + if err != nil { + log.Println(err) + os.Exit(1) + } + f.WriteString(string(diffJSON) + "\n") +} + func (m *migrationUtil) SetFetched(raw []bson.M) { m.rawData = append(m.rawData, raw...) } @@ -498,6 +516,7 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio writtenCount += int(results.ModifiedCount) writeLastItemUpdate(m.lastUpdatedId, m.config.dryRun) + m.writeDiff(batch, m.updatedCount, m.updatedCount+writtenCount) } m.updates = []mongo.WriteModel{} m.updatedCount = m.updatedCount + writtenCount diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index d241458d00..97c9bb2ef2 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -3,8 +3,6 @@ package utils import ( "encoding/json" "fmt" - "log" - "os" "slices" "strings" "time" @@ -36,20 +34,6 @@ import ( structureValidator "github.com/tidepool-org/platform/structure/validator" ) -func logDiff(id string, updates interface{}) { - updatesJSON, _ := json.Marshal(updates) - if string(updatesJSON) != "[]" { - f, err := os.OpenFile("diff.log", - os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - log.Println(err) - os.Exit(1) - } - defer f.Close() - f.WriteString(fmt.Sprintf(`{"_id":"%s","diff":%s},`, id, string(updatesJSON))) - } -} - func getBGValuePrecision(val interface{}) *float64 { floatStr := fmt.Sprintf("%v", val) floatParts := strings.Split(floatStr, ".") @@ -256,7 +240,7 @@ func BuildPlatformDatum(objID string, objType string, objectData map[string]inte return datum, nil } -func GetDatumChanges(id string, datum interface{}, original map[string]interface{}, logging bool) ([]bson.M, error) { +func GetDatumChanges(id string, datum interface{}, original map[string]interface{}) ([]bson.M, error) { outgoingJSONData, err := json.Marshal(datum) if err != nil { @@ -324,13 +308,10 @@ func GetDatumChanges(id string, datum interface{}, original map[string]interface if len(unset) > 0 { difference = append(difference, bson.M{"$unset": unset}) } - if logging { - logDiff(id, difference) - } return difference, nil } -func ProcessDatum(dataID string, dataType string, bsonData bson.M, logChanges bool) ([]bson.M, error) { +func ProcessDatum(dataID string, dataType string, bsonData bson.M) ([]bson.M, error) { if err := ApplyBaseChanges(bsonData, dataType); err != nil { return nil, err @@ -350,7 +331,7 @@ func ProcessDatum(dataID string, dataType string, bsonData bson.M, logChanges bo return nil, err } - updates, err := GetDatumChanges(dataID, datum, ojbData, logChanges) + updates, err := GetDatumChanges(dataID, datum, ojbData) if err != nil { return nil, err } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 93553ec619..40c2fd76ee 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -396,27 +396,27 @@ var _ = Describe("back-37", func() { }) It("has no difference", func() { - diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject, false) + diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) Expect(err).To(BeNil()) Expect(diff).ToNot(BeNil()) Expect(diff).To(Equal([]bson.M{})) }) It("set for missing properties", func() { delete(incomingObject, "deliveryType") - diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject, false) + diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) Expect(err).To(BeNil()) Expect(diff).To(Equal([]bson.M{{"$set": bson.M{"deliveryType": "automated"}}})) }) It("unset for unwanted properties", func() { incomingObject["random"] = map[string]interface{}{"extra": true} - diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject, false) + diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) Expect(err).To(BeNil()) Expect(diff).To(Equal([]bson.M{{"$unset": bson.M{"random": ""}}})) }) It("no difference when inner payload changes", func() { datumObject["payload"] = map[string]interface{}{"stuff": true} - diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject, false) + diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) Expect(err).To(BeNil()) Expect(diff).To(Equal([]bson.M{})) }) From 314f53b356d46b6da077e81c38f5eabbe9c7980c Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 21 Feb 2024 13:30:36 +1300 Subject: [PATCH 226/413] group updates by type for diff --- .../jellyfish_migration.go | 12 +-- .../utils/migrationUtil.go | 95 +++++++++++-------- 2 files changed, 59 insertions(+), 48 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index f29692d170..de66b20464 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -237,12 +237,12 @@ func (m *Migration) fetchAndProcess() bool { m.migrationUtil.OnError(utils.ErrorData{Error: err, ItemID: itemID, ItemType: itemType}) } if !m.config.audit { - for _, update := range updates { - updateOp := mongo.NewUpdateOneModel() - updateOp.SetFilter(bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}) - updateOp.SetUpdate(update) - m.migrationUtil.SetUpdates(updateOp) - } + m.migrationUtil.SetUpdates(utils.UpdateData{ + Filter: bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}, + ItemID: itemID, + ItemType: itemType, + Updates: updates, + }) } m.migrationUtil.SetLastProcessed(itemID) all = append(all, item) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index c9e6d22ccb..b0c6745a40 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -41,19 +41,21 @@ type migrationUtil struct { client *mongo.Client config *MigrationUtilConfig updates []mongo.WriteModel - //dataUpdates []Update - groupedErrors groupedErrors - rawData []bson.M - errorsCount int - updatedCount int - lastUpdatedId string - startedAt time.Time + groupedDiffs map[string][]UpdateData + groupedErrors groupedErrors + rawData []bson.M + errorsCount int + updatedCount int + lastUpdatedId string + startedAt time.Time } -// type Update struct { -// ItemID string `json:"_id"` -// MongoWrites []mongo.WriteModel `json:"diff"` -// } +type UpdateData struct { + Filter interface{} `json:"-"` + ItemID string `json:"_id"` + ItemType string `json:"-"` + Updates []bson.M `json:"diff"` +} type ErrorData struct { Error error `json:"error"` @@ -76,8 +78,7 @@ type MigrationUtil interface { Initialize(ctx context.Context, dataC *mongo.Collection) error Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func() bool) error OnError(data ErrorData) - //SetUpdate(update Update) - SetUpdates(update ...*mongo.UpdateOneModel) + SetUpdates(data UpdateData) SetLastProcessed(lastID string) SetFetched(raw []bson.M) GetLastID() string @@ -105,10 +106,10 @@ func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client, lastID updates: []mongo.WriteModel{}, rawData: []bson.M{}, groupedErrors: groupedErrors{}, - //dataUpdates: []Update{}, - errorsCount: 0, - updatedCount: 0, - startedAt: time.Now(), + groupedDiffs: map[string][]UpdateData{}, + errorsCount: 0, + updatedCount: 0, + startedAt: time.Now(), } if lastID != nil { m.lastUpdatedId = *lastID @@ -154,16 +155,16 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe return nil } -func (m *migrationUtil) SetUpdates(update ...*mongo.UpdateOneModel) { - for _, u := range update { - m.updates = append(m.updates, u) +func (m *migrationUtil) SetUpdates(data UpdateData) { + m.groupedDiffs[data.ItemType] = append(m.groupedDiffs[data.ItemType], data) + for _, u := range data.Updates { + updateOp := mongo.NewUpdateOneModel() + updateOp.Filter = data.Filter + updateOp.SetUpdate(u) + m.updates = append(m.updates, updateOp) } } -// func (m *migrationUtil) SetUpdate(update Update) { -// m.dataUpdates = append(m.dataUpdates, update) -// } - func (m *migrationUtil) SetLastProcessed(lastID string) { m.lastUpdatedId = lastID } @@ -201,22 +202,31 @@ func (m *migrationUtil) writeErrors(groupLimit *int) { } } -func (m *migrationUtil) writeDiff(updates []mongo.WriteModel, from int, to int) { - now := time.Now() - logName := fmt.Sprintf("updates/diff%s_%d-%d.log", now.Format(time.TimeOnly), from, to) - f, err := os.OpenFile(logName, - os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - log.Println(err) - os.Exit(1) - } - defer f.Close() - diffJSON, err := json.Marshal(updates) - if err != nil { - log.Println(err) - os.Exit(1) +func (m *migrationUtil) writeDiff(groupLimit *int) { + timestamp := strings.Replace(time.Now().Format(time.Stamp), " ", "-", -1) + for group, diffs := range m.groupedDiffs { + if groupLimit != nil { + if len(diffs) < *groupLimit { + continue + } + } + logName := fmt.Sprintf("updates/diff_%s_%s.log", group, timestamp) + f, err := os.OpenFile(logName, + os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Println(err) + os.Exit(1) + } + defer f.Close() + for _, data := range diffs { + diffJSON, err := json.Marshal(data) + if err != nil { + log.Println(err) + os.Exit(1) + } + f.WriteString(string(diffJSON) + "\n") + } } - f.WriteString(string(diffJSON) + "\n") } func (m *migrationUtil) SetFetched(raw []bson.M) { @@ -516,17 +526,18 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio writtenCount += int(results.ModifiedCount) writeLastItemUpdate(m.lastUpdatedId, m.config.dryRun) - m.writeDiff(batch, m.updatedCount, m.updatedCount+writtenCount) } m.updates = []mongo.WriteModel{} m.updatedCount = m.updatedCount + writtenCount + writeLimit := 500 if m.config.dryRun { log.Println("dry-run so no changes applied") + m.writeDiff(&writeLimit) } else { log.Printf("write took [%s] for [%d] items\n", time.Since(writeStart), writtenCount) - errorWriteLimit := 500 m.GetStats().report() - m.writeErrors(&errorWriteLimit) + m.writeErrors(&writeLimit) + m.writeDiff(&writeLimit) } return nil } From 57b99b0f1b14d856c00e46e2b1f491c00b49fc6d Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 21 Feb 2024 13:38:57 +1300 Subject: [PATCH 227/413] flush diffs at end --- migrations/20231128_jellyfish_migration/utils/migrationUtil.go | 1 + 1 file changed, 1 insertion(+) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index b0c6745a40..1f2e769c48 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -152,6 +152,7 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe } m.GetStats().report() m.writeErrors(nil) + m.writeDiff(nil) return nil } From bba5b9fa5e8cd6d4ec1267b733e079e1a76ce1c4 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 21 Feb 2024 15:36:28 +1300 Subject: [PATCH 228/413] remove audit, set _deduplicator correctly on updates --- .../jellyfish_migration.go | 18 ++--- .../utils/migrationUtil.go | 2 + .../utils/utils.go | 5 ++ .../utils/utils_test.go | 73 +++++++++++++------ 4 files changed, 66 insertions(+), 32 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index de66b20464..10755b6091 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -27,7 +27,6 @@ type config struct { cap int uri string dryRun bool - audit bool stopOnErr bool userID string lastUpdatedId string @@ -84,7 +83,7 @@ func (m *Migration) RunAndExit() { return err } if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndProcess); err != nil { - log.Printf("audit failed: %s", err) + log.Printf("processing failed: %s", err) return err } return nil @@ -118,11 +117,11 @@ func (m *Migration) Initialize() error { Usage: "stop migration on error", Destination: &m.config.stopOnErr, }, - cli.BoolFlag{ - Name: "audit", - Usage: "audit data", - Destination: &m.config.audit, - }, + // cli.BoolFlag{ + // Name: "audit", + // Usage: "audit data", + // Destination: &m.config.audit, + // }, cli.IntFlag{ Name: "cap", Usage: "max number of records migrate", @@ -235,14 +234,15 @@ func (m *Migration) fetchAndProcess() bool { updates, err := utils.ProcessDatum(itemID, itemType, item) if err != nil { m.migrationUtil.OnError(utils.ErrorData{Error: err, ItemID: itemID, ItemType: itemType}) - } - if !m.config.audit { + } else { + //if !m.config.audit { //TODO dry run should be audit m.migrationUtil.SetUpdates(utils.UpdateData{ Filter: bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}, ItemID: itemID, ItemType: itemType, Updates: updates, }) + //} } m.migrationUtil.SetLastProcessed(itemID) all = append(all, item) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 1f2e769c48..503a98ebb4 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -332,6 +332,7 @@ func (m *migrationUtil) getAdminDB() *mongo.Database { func writeLastItemUpdate(itemID string, dryRun bool) { if strings.TrimSpace(itemID) != "" { + //TODO - i think we still want this so we can keep processing in order if dryRun { log.Printf("dry run so not setting lastUpdatedId %s", itemID) return @@ -516,6 +517,7 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio } if m.config.dryRun { + //TODO clean this up a bit writtenCount += len(batch) continue } diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 97c9bb2ef2..b8f0dabc8d 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -252,6 +252,10 @@ func GetDatumChanges(id string, datum interface{}, original map[string]interface return nil, err } + if deduplicator := processedObject["deduplicator"]; deduplicator != nil { + processedObject["_deduplicator"] = deduplicator + } + // these are extras that we want to leave on the // original object so don't compare notRequired := []string{ @@ -266,6 +270,7 @@ func GetDatumChanges(id string, datum interface{}, original map[string]interface "guid", "modifiedTime", "uploadId", + "deduplicator", } for _, key := range notRequired { diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 40c2fd76ee..fd2f72783e 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -38,25 +38,40 @@ var _ = Describe("back-37", func() { return bsonData } + var datumSetup = func(testObj map[string]interface{}) (map[string]interface{}, error) { + bsonData := getBSONData(testObj) + objType := fmt.Sprintf("%v", bsonData["type"]) + utils.ApplyBaseChanges(bsonData, objType) + incomingJSONData, err := json.Marshal(bsonData) + if err != nil { + return nil, err + } + cleanedObject := map[string]interface{}{} + if err := json.Unmarshal(incomingJSONData, &cleanedObject); err != nil { + return nil, err + } + return cleanedObject, nil + } + var _ = Describe("BuildPlatformDatum", func() { - var setup = func(testObj map[string]interface{}) (map[string]interface{}, error) { - bsonData := getBSONData(testObj) - objType := fmt.Sprintf("%v", bsonData["type"]) - utils.ApplyBaseChanges(bsonData, objType) - incomingJSONData, err := json.Marshal(bsonData) - if err != nil { - return nil, err - } - cleanedObject := map[string]interface{}{} - if err := json.Unmarshal(incomingJSONData, &cleanedObject); err != nil { - return nil, err - } - return cleanedObject, nil - } + // var setup = func(testObj map[string]interface{}) (map[string]interface{}, error) { + // bsonData := getBSONData(testObj) + // objType := fmt.Sprintf("%v", bsonData["type"]) + // utils.ApplyBaseChanges(bsonData, objType) + // incomingJSONData, err := json.Marshal(bsonData) + // if err != nil { + // return nil, err + // } + // cleanedObject := map[string]interface{}{} + // if err := json.Unmarshal(incomingJSONData, &cleanedObject); err != nil { + // return nil, err + // } + // return cleanedObject, nil + // } It("should successfully build basal datum", func() { - basalData, err := setup(test.AutomatedBasalTandem) + basalData, err := datumSetup(test.AutomatedBasalTandem) Expect(err).To(BeNil()) datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", basalData["_id"]), basal.Type, basalData) Expect(err).To(BeNil()) @@ -65,7 +80,7 @@ var _ = Describe("back-37", func() { }) It("should successfully build dexcom g5 datum", func() { - cbgData, err := setup(test.CBGDexcomG5MobDatum) + cbgData, err := datumSetup(test.CBGDexcomG5MobDatum) Expect(err).To(BeNil()) datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", cbgData["_id"]), continuous.Type, cbgData) Expect(err).To(BeNil()) @@ -73,7 +88,7 @@ var _ = Describe("back-37", func() { Expect((*datum).GetType()).To(Equal(continuous.Type)) }) It("should successfully build carelink pump settings", func() { - pSettingsData, err := setup(test.PumpSettingsCarelink) + pSettingsData, err := datumSetup(test.PumpSettingsCarelink) Expect(err).To(BeNil()) datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", pSettingsData["_id"]), pump.Type, pSettingsData) Expect(err).To(BeNil()) @@ -81,7 +96,7 @@ var _ = Describe("back-37", func() { Expect((*datum).GetType()).To(Equal(pump.Type)) }) It("should successfully build omnipod pump settings", func() { - pSettingsData, err := setup(test.PumpSettingsOmnipod) + pSettingsData, err := datumSetup(test.PumpSettingsOmnipod) Expect(err).To(BeNil()) datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", pSettingsData["_id"]), pump.Type, pSettingsData) Expect(err).To(BeNil()) @@ -89,7 +104,7 @@ var _ = Describe("back-37", func() { Expect((*datum).GetType()).To(Equal(pump.Type)) }) It("should successfully build tandem pump settings", func() { - pSettingsData, err := setup(test.PumpSettingsTandem) + pSettingsData, err := datumSetup(test.PumpSettingsTandem) Expect(err).To(BeNil()) datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", pSettingsData["_id"]), pump.Type, pSettingsData) Expect(err).To(BeNil()) @@ -97,7 +112,7 @@ var _ = Describe("back-37", func() { Expect((*datum).GetType()).To(Equal(pump.Type)) }) It("should successfully build tandem wizard", func() { - calcData, err := setup(test.WizardTandem) + calcData, err := datumSetup(test.WizardTandem) Expect(err).To(BeNil()) datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", calcData["_id"]), calculator.Type, calcData) Expect(err).To(BeNil()) @@ -105,7 +120,7 @@ var _ = Describe("back-37", func() { Expect((*datum).GetType()).To(Equal(calculator.Type)) }) It("should successfully build device event", func() { - deviceEventData, err := setup(test.ReservoirChange) + deviceEventData, err := datumSetup(test.ReservoirChange) Expect(err).To(BeNil()) datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", deviceEventData["_id"]), device.Type, deviceEventData) Expect(err).To(BeNil()) @@ -113,7 +128,7 @@ var _ = Describe("back-37", func() { Expect((*datum).GetType()).To(Equal(device.Type)) }) It("should successfully build cgm settings", func() { - deviceEventData, err := setup(test.CGMSetting) + deviceEventData, err := datumSetup(test.CGMSetting) Expect(err).To(BeNil()) datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", deviceEventData["_id"]), cgm.Type, deviceEventData) Expect(err).To(BeNil()) @@ -407,13 +422,25 @@ var _ = Describe("back-37", func() { Expect(err).To(BeNil()) Expect(diff).To(Equal([]bson.M{{"$set": bson.M{"deliveryType": "automated"}}})) }) + It("set _deduplicator correctly", func() { + calcData, _ := datumSetup(test.WizardTandem) + id := fmt.Sprintf("%v", calcData["_id"]) + datum, _ := utils.BuildPlatformDatum(id, calculator.Type, calcData) + diff, err := utils.GetDatumChanges(id, datum, calcData) + Expect(err).To(BeNil()) + Expect(diff[0]["$set"]).To( + Equal( + bson.M{ + "time": "2022-06-21T22:40:07.732Z", + "_deduplicator": map[string]interface{}{"hash": "o6ybZQtDZ95FvuV0zYGphri2SIGesbLCbkHxc1wbbEE="}, + })) + }) It("unset for unwanted properties", func() { incomingObject["random"] = map[string]interface{}{"extra": true} diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) Expect(err).To(BeNil()) Expect(diff).To(Equal([]bson.M{{"$unset": bson.M{"random": ""}}})) }) - It("no difference when inner payload changes", func() { datumObject["payload"] = map[string]interface{}{"stuff": true} diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) From 6474069e842bc467c1f271054f2c1c1c2abf61ff Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 21 Feb 2024 15:44:31 +1300 Subject: [PATCH 229/413] filter out empty updates --- .../20231128_jellyfish_migration/jellyfish_migration.go | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 10755b6091..8bd5d38b91 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -117,11 +117,6 @@ func (m *Migration) Initialize() error { Usage: "stop migration on error", Destination: &m.config.stopOnErr, }, - // cli.BoolFlag{ - // Name: "audit", - // Usage: "audit data", - // Destination: &m.config.audit, - // }, cli.IntFlag{ Name: "cap", Usage: "max number of records migrate", @@ -234,15 +229,13 @@ func (m *Migration) fetchAndProcess() bool { updates, err := utils.ProcessDatum(itemID, itemType, item) if err != nil { m.migrationUtil.OnError(utils.ErrorData{Error: err, ItemID: itemID, ItemType: itemType}) - } else { - //if !m.config.audit { //TODO dry run should be audit + } else if len(updates) > 0 { m.migrationUtil.SetUpdates(utils.UpdateData{ Filter: bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}, ItemID: itemID, ItemType: itemType, Updates: updates, }) - //} } m.migrationUtil.SetLastProcessed(itemID) all = append(all, item) From fb10961b1550cf7f72486fff98b3815ca113d10d Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 21 Feb 2024 16:01:45 +1300 Subject: [PATCH 230/413] reset after written --- migrations/20231128_jellyfish_migration/utils/migrationUtil.go | 1 + 1 file changed, 1 insertion(+) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 503a98ebb4..3b717bc0d8 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -227,6 +227,7 @@ func (m *migrationUtil) writeDiff(groupLimit *int) { } f.WriteString(string(diffJSON) + "\n") } + m.groupedDiffs[group] = []UpdateData{} } } From 1ede9ee8349fdacfd44b96817adfafeab415ac02 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 21 Feb 2024 16:51:14 +1300 Subject: [PATCH 231/413] debug status changes --- migrations/20231128_jellyfish_migration/utils/utils.go | 6 ++++-- migrations/20231128_jellyfish_migration/utils/utils_test.go | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index b8f0dabc8d..a3970db582 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -3,6 +3,7 @@ package utils import ( "encoding/json" "fmt" + "log" "slices" "strings" "time" @@ -119,8 +120,9 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { subType := fmt.Sprintf("%v", bsonData["subType"]) switch subType { case reservoirchange.SubType, alarm.SubType: - bsonData["statusId"] = bsonData["status"] - delete(bsonData, "status") + log.Printf("status _id=%s statusId=%v status=%v", bsonData["_id"], bsonData["statusId"], bsonData["status"]) + //bsonData["statusId"] = bsonData["status"] + //delete(bsonData, "status") } } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index fd2f72783e..3c0992a2b6 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -120,6 +120,7 @@ var _ = Describe("back-37", func() { Expect((*datum).GetType()).To(Equal(calculator.Type)) }) It("should successfully build device event", func() { + Skip("TODO sort out status converions") deviceEventData, err := datumSetup(test.ReservoirChange) Expect(err).To(BeNil()) datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", deviceEventData["_id"]), device.Type, deviceEventData) @@ -286,6 +287,7 @@ var _ = Describe("back-37", func() { return datum } It("should convert to statusId", func() { + Skip("TODO sort out status converions") deviceEvent := newReservoirChange() deviceEventData := getBSONData(deviceEvent) deviceEventData["status"] = "some-status-id" From b8589976062d1f54289fbdaf76de9ee2343cd98c Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 21 Feb 2024 16:57:37 +1300 Subject: [PATCH 232/413] status ID checks --- migrations/20231128_jellyfish_migration/utils/utils.go | 10 ++++++---- .../20231128_jellyfish_migration/utils/utils_test.go | 2 -- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index a3970db582..2383d91f20 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -3,7 +3,6 @@ package utils import ( "encoding/json" "fmt" - "log" "slices" "strings" "time" @@ -120,9 +119,12 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { subType := fmt.Sprintf("%v", bsonData["subType"]) switch subType { case reservoirchange.SubType, alarm.SubType: - log.Printf("status _id=%s statusId=%v status=%v", bsonData["_id"], bsonData["statusId"], bsonData["status"]) - //bsonData["statusId"] = bsonData["status"] - //delete(bsonData, "status") + if status := bsonData["status"]; status != nil { + if statusID, ok := status.(string); ok { + bsonData["statusId"] = statusID + delete(bsonData, "status") + } + } } } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 3c0992a2b6..fd2f72783e 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -120,7 +120,6 @@ var _ = Describe("back-37", func() { Expect((*datum).GetType()).To(Equal(calculator.Type)) }) It("should successfully build device event", func() { - Skip("TODO sort out status converions") deviceEventData, err := datumSetup(test.ReservoirChange) Expect(err).To(BeNil()) datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", deviceEventData["_id"]), device.Type, deviceEventData) @@ -287,7 +286,6 @@ var _ = Describe("back-37", func() { return datum } It("should convert to statusId", func() { - Skip("TODO sort out status converions") deviceEvent := newReservoirChange() deviceEventData := getBSONData(deviceEvent) deviceEventData["status"] = "some-status-id" From e4ff330bc89ed90acf2c5b19c6b142485c1fc2a0 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 22 Feb 2024 11:57:58 +1300 Subject: [PATCH 233/413] debug for bolusID on wizard --- .../utils/utils.go | 9 +- .../utils/utils_test.go | 327 +----------------- 2 files changed, 8 insertions(+), 328 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 2383d91f20..e610663c9a 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -3,6 +3,7 @@ package utils import ( "encoding/json" "fmt" + "log" "slices" "strings" "time" @@ -112,8 +113,11 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { } case calculator.Type: if bolus := bsonData["bolus"]; bolus != nil { - //TODO ignore these, the property is just a pointer to the actual bolus - delete(bsonData, "bolus") + if bolusID, ok := bolus.(string); ok { + log.Printf("## setting the %v bolus reference %v", calculator.Type, bolusID) + bsonData["bolusId"] = bolusID + delete(bsonData, "bolus") + } } case device.Type: subType := fmt.Sprintf("%v", bsonData["subType"]) @@ -207,6 +211,7 @@ func BuildPlatformDatum(objID string, objType string, objectData map[string]inte validator.Float64("percent", parser.Float64("percent")) validator.Float64("rate", parser.Float64("rate")) validator.Int("duration", parser.Int("duration")) + validator.String("bolusId", parser.String("bolusId")) } parser.NotParsed() diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index fd2f72783e..f69bc54495 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -54,22 +54,6 @@ var _ = Describe("back-37", func() { } var _ = Describe("BuildPlatformDatum", func() { - - // var setup = func(testObj map[string]interface{}) (map[string]interface{}, error) { - // bsonData := getBSONData(testObj) - // objType := fmt.Sprintf("%v", bsonData["type"]) - // utils.ApplyBaseChanges(bsonData, objType) - // incomingJSONData, err := json.Marshal(bsonData) - // if err != nil { - // return nil, err - // } - // cleanedObject := map[string]interface{}{} - // if err := json.Unmarshal(incomingJSONData, &cleanedObject); err != nil { - // return nil, err - // } - // return cleanedObject, nil - // } - It("should successfully build basal datum", func() { basalData, err := datumSetup(test.AutomatedBasalTandem) Expect(err).To(BeNil()) @@ -78,7 +62,6 @@ var _ = Describe("back-37", func() { Expect(datum).ToNot(BeNil()) Expect((*datum).GetType()).To(Equal(basal.Type)) }) - It("should successfully build dexcom g5 datum", func() { cbgData, err := datumSetup(test.CBGDexcomG5MobDatum) Expect(err).To(BeNil()) @@ -239,7 +222,6 @@ var _ = Describe("back-37", func() { Expect(err.Error()).To(Equal("pumpSettings.sleepSchedules has an invalid day of week not-a-day")) }) }) - Context("datum with glucose", func() { var newContinuous = func(units *string) *continuous.Continuous { datum := continuous.New() @@ -391,7 +373,7 @@ var _ = Describe("back-37", func() { }) }) - var _ = Describe("GetDifference", func() { + var _ = Describe("GetDatumChanges", func() { const expectedID = "difference-id" @@ -448,312 +430,5 @@ var _ = Describe("back-37", func() { Expect(diff).To(Equal([]bson.M{})) }) }) - - // TODO: switch to audit + update - // var _ = Describe("GetDatumUpdates", func() { - // var existingBolusDatum bson.M - // const expectedID = "some-id" - - // var getBSONData = func(datum interface{}) bson.M { - // var bsonData bson.M - // bsonAsByte, _ := bson.Marshal(&datum) - // bson.Unmarshal(bsonAsByte, &bsonData) - // return bsonData - // } - - // BeforeEach(func() { - // datum := bolusTest.RandomBolus() - // *datum.ID = expectedID - // *datum.UserID = "some-user-id" - // *datum.DeviceID = "some-device-id" - // datum.SubType = "some-subtype" - // theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") - // *datum.Time = theTime - // existingBolusDatum = getBSONData(datum) - // existingBolusDatum["_id"] = expectedID - // Expect(existingBolusDatum).ToNot(BeNil()) - // }) - - // Context("_deduplicator hash", func() { - // DescribeTable("should", - // func(getInput func() bson.M, expectedUpdates []bson.M, expectError bool) { - // input := getInput() - // actualID, actualUpdates, err := utils.GetDatumUpdates(input) - // if expectError { - // Expect(err).ToNot(BeNil()) - // Expect(actualUpdates).To(BeNil()) - // return - // } - // Expect(err).To(BeNil()) - // if expectedUpdates != nil { - // Expect(actualUpdates).To(Equal(expectedUpdates)) - // Expect(actualID).To(Equal(expectedID)) - // } else { - // Expect(actualUpdates).To(BeNil()) - // } - // }, - // Entry("error when missing _userId", func() bson.M { - // existingBolusDatum["_userId"] = nil - // return existingBolusDatum - // }, nil, true), - // Entry("error when missing deviceId", func() bson.M { - // existingBolusDatum["deviceId"] = nil - // return existingBolusDatum - // }, nil, true), - // Entry("error when missing time", func() bson.M { - // existingBolusDatum["time"] = nil - // return existingBolusDatum - // }, nil, true), - // Entry("error when missing type", func() bson.M { - // existingBolusDatum["type"] = nil - // return existingBolusDatum - // }, nil, true), - // Entry("adds hash when vaild", func() bson.M { - // return existingBolusDatum - // }, - // []bson.M{ - // {"$set": bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}}, - // }, - // false, - // ), - // ) - // }) - - // Context("pumpSettings", func() { - - // var pumpSettingsDatum *pump.Pump - - // BeforeEach(func() { - // mmolL := pump.DisplayBloodGlucoseUnitsMmolPerL - // pumpSettingsDatum = pumpTest.NewPump(&mmolL) - // *pumpSettingsDatum.ID = expectedID - // *pumpSettingsDatum.UserID = "some-user-id" - // *pumpSettingsDatum.DeviceID = "some-device-id" - // theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") - // *pumpSettingsDatum.Time = theTime - // }) - - // Context("with mis-named jellyfish bolus", func() { - // var bolusData = &pump.BolusMap{ - // "bolus-1": pumpTest.NewRandomBolus(), - // "bolus-2": pumpTest.NewRandomBolus(), - // } - // var settingsBolusDatum bson.M - - // BeforeEach(func() { - // settingsBolusDatum = getBSONData(pumpSettingsDatum) - // settingsBolusDatum["bolus"] = bolusData - // settingsBolusDatum["_id"] = expectedID - // }) - - // DescribeTable("should", - // func(getInput func() bson.M, expected []bson.M, expectError bool) { - // input := getInput() - // _, actual, err := utils.GetDatumUpdates(input) - // if expectError { - // Expect(err).ToNot(BeNil()) - // Expect(actual).To(BeNil()) - // return - // } - // Expect(err).To(BeNil()) - // if expected != nil { - // Expect(actual).To(BeEquivalentTo(expected)) - // } else { - // Expect(actual).To(BeNil()) - // } - // }, - - // Entry("do nothing when wrong type", - // func() bson.M { - // return existingBolusDatum - // }, - // []bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}}}, - // false, - // ), - // Entry("do nothing when has no bolus", - // func() bson.M { - // settingsBolusDatum["bolus"] = nil - // return settingsBolusDatum - // }, - // []bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}}}, - // false, - // ), - // Entry("add boluses when bolus found", - // func() bson.M { - // settingsBolusDatum["bolus"] = bolusData - // return settingsBolusDatum - // }, - // []bson.M{ - // {"$set": bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}}, - // {"$rename": bson.M{"bolus": "boluses"}}, - // }, - // false, - // ), - // ) - // }) - // Context("unordered sleepSchedules", func() { - // expectedSleepSchedulesMap := &pump.SleepScheduleMap{} - // var invalidDays *pump.SleepSchedule - // var s1Days *pump.SleepSchedule - // var s2Days *pump.SleepSchedule - // var sleepSchedulesDatum bson.M - // BeforeEach(func() { - // s1 := pumpTest.RandomSleepSchedule() - // s2 := pumpTest.RandomSleepSchedule() - // (*expectedSleepSchedulesMap)["1"] = s1 - // (*expectedSleepSchedulesMap)["2"] = s2 - - // s1Days = pumpTest.CloneSleepSchedule(s1) - // for key, day := range *s1Days.Days { - // (*s1Days.Days)[key] = strings.ToUpper(day) - // } - // s2Days = pumpTest.CloneSleepSchedule(s2) - // for key, day := range *s2Days.Days { - // (*s2Days.Days)[key] = strings.ToUpper(day) - // } - // invalidDays = pumpTest.CloneSleepSchedule(s2) - // invalidDays.Days = &[]string{"not-a-day", common.DayFriday} - - // //to ensure correct sorting - // expectedSleepSchedulesMap.Normalize(normalizer.New()) - - // Expect(expectedSleepSchedulesMap).ToNot(BeNil()) - // pumpSettingsDatum.SleepSchedules = nil - // sleepSchedulesDatum = getBSONData(pumpSettingsDatum) - // sleepSchedulesDatum["_id"] = expectedID - // sleepSchedulesDatum["bolus"] = nil //remove as not testing here - // }) - - // It("does nothing when wrong type", func() { - // _, actual, err := utils.GetDatumUpdates(existingBolusDatum) - // Expect(err).To(BeNil()) - // Expect(len(actual)).To(Equal(1)) - // Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "FVjexdlY6mWkmoh5gdmtdhzVH4R03+iGE81ro08/KcE="}}}})) - // }) - // It("does nothing when no sleepSchedules", func() { - // sleepSchedulesDatum["sleepSchedules"] = nil - // _, actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) - // Expect(err).To(BeNil()) - // Expect(len(actual)).To(Equal(1)) - // Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "RlrPcuPDfRim29UwnM7Yf0Ib0Ht4F35qvHu62CCYXnM="}}}})) - // }) - // It("returns updated sleepSchedules when valid", func() { - // sleepSchedulesDatum["sleepSchedules"] = []*pump.SleepSchedule{s1Days, s2Days} - // _, actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) - // Expect(err).To(BeNil()) - // Expect(len(actual)).To(Equal(1)) - // setData := actual[0]["$set"].(bson.M) - // Expect(setData["sleepSchedules"]).ToNot(BeNil()) - // Expect(setData["sleepSchedules"]).To(Equal(expectedSleepSchedulesMap)) - // }) - // It("returns error when sleepSchedules have invalid days", func() { - // sleepSchedulesDatum["sleepSchedules"] = []*pump.SleepSchedule{invalidDays} - // _, actual, err := utils.GetDatumUpdates(sleepSchedulesDatum) - // Expect(err).ToNot(BeNil()) - // Expect(err.Error()).To(Equal("pumpSettings.sleepSchedules has an invalid day of week not-a-day")) - // Expect(actual).To(BeNil()) - // }) - // }) - // }) - // Context("datum with glucose", func() { - - // var newContinuous = func(units *string) *continuous.Continuous { - // datum := continuous.New() - // datum.Glucose = *glucoseTest.NewGlucose(units) - // datum.Type = "cbg" - // *datum.ID = expectedID - // *datum.UserID = "some-user-id" - // *datum.DeviceID = "some-device-id" - // theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") - // *datum.Time = theTime - // return datum - // } - - // DescribeTable("should", - // func(getInput func() bson.M, expected []bson.M, expectError bool) { - // input := getInput() - // _, actual, err := utils.GetDatumUpdates(input) - // if expectError { - // Expect(err).ToNot(BeNil()) - // Expect(actual).To(BeNil()) - // return - // } - // Expect(err).To(BeNil()) - // if expected != nil { - // Expect(actual).To(BeEquivalentTo(expected)) - // } else { - // Expect(actual).To(BeNil()) - // } - // }, - - // Entry("do nothing when not normailzed", - // func() bson.M { - // mmolL := glucose.MmolL - // cbg := newContinuous(&mmolL) - // cbgData := getBSONData(cbg) - // cbgData["_id"] = expectedID - // cbgData["value"] = 9.5 - // return cbgData - // }, - // []bson.M{{"$set": bson.M{ - // "_deduplicator": bson.M{"hash": "lLCOZJMLvNaBx7dMc31bbX4zwSfPvxcUd0Z1uU/YIAs="}, - // }}}, - // false, - // ), - // Entry("update value when normailzed", - // func() bson.M { - // mgdL := glucose.MgdL - // cbg := newContinuous(&mgdL) - // cbgData := getBSONData(cbg) - // cbgData["_id"] = expectedID - // cbgData["value"] = 180 - - // return cbgData - // }, - // []bson.M{{"$set": bson.M{ - // "_deduplicator": bson.M{"hash": "FZtVRkliues5vAt25ZK+WDAqa4Q6tAAe9h2PdKM15Q4="}, - // "value": pointer.FromFloat64(9.99135), - // "units": pointer.FromString(glucose.MmolL), - // }}}, - // false, - // ), - // ) - // }) - // Context("Historic datum", func() { - // It("g5 dexcom", func() { - // actualID, actual, err := utils.GetDatumUpdates(getBSONData(test.CBGDexcomG5MobDatum)) - // Expect(err).To(BeNil()) - // Expect(actual).ToNot(BeNil()) - // Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "TKJurm+/SuA5tarn/nATa7Nw0LXgwGel67lgJihUctM="}}}})) - // Expect(actualID).ToNot(BeEmpty()) - // }) - - // It("carelink medtronic pumpSettings", func() { - // actualID, actual, err := utils.GetDatumUpdates(getBSONData(test.PumpSettingsCarelink)) - // Expect(err).To(BeNil()) - // Expect(actual).ToNot(BeNil()) - // Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "NC17pw1UAaab50iChhQXJ+N9dTi6GduTy9UjsMHolow="}}}})) - // Expect(actualID).ToNot(BeEmpty()) - // }) - - // It("tandem pumpSettings", func() { - // actualID, actual, err := utils.GetDatumUpdates(getBSONData(test.PumpSettingsTandem)) - // Expect(err).To(BeNil()) - // Expect(actual).ToNot(BeNil()) - // Expect(len(actual)).To(Equal(1)) - // Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "bpKLJbi5JfqD7N0WJ1vj0ck03c9EZ3U0H09TCLhdd3k="}}}})) - // Expect(actualID).ToNot(BeEmpty()) - // }) - - // It("omnipod pumpSettings", func() { - // actualID, actual, err := utils.GetDatumUpdates(getBSONData(test.PumpSettingsOmnipod)) - // Expect(err).To(BeNil()) - // Expect(actual).ToNot(BeNil()) - // Expect(actual).To(Equal([]bson.M{{"$set": bson.M{"_deduplicator": bson.M{"hash": "oH7/6EEgUjRTeafEpm74fVTYMBvMdQ65/rhg0oFoev8="}}}})) - // Expect(actualID).ToNot(BeEmpty()) - // }) - - // }) - // }) }) }) From 88eeba98e8cb04cc0d57742899be053b9d6bb7ae Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 22 Feb 2024 15:24:11 +1300 Subject: [PATCH 234/413] changes for wizard datum with bolus string --- .../utils/test/data.go | 1 + .../utils/utils.go | 3 +- .../utils/utils_test.go | 75 +++++++++---------- 3 files changed, 39 insertions(+), 40 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go index 354460d0a1..0662628565 100644 --- a/migrations/20231128_jellyfish_migration/utils/test/data.go +++ b/migrations/20231128_jellyfish_migration/utils/test/data.go @@ -190,6 +190,7 @@ func tandemWizardDatum() map[string]interface{} { datum["rate"] = 0.335 datum["percent"] = 0.47857142857142865 datum["conversionOffset"] = 0 + datum["bolus"] = "g2h6nohp5sdndpvl2l8kdete00lle4gt" return datum } diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index e610663c9a..69c56d0fc0 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -3,7 +3,6 @@ package utils import ( "encoding/json" "fmt" - "log" "slices" "strings" "time" @@ -114,7 +113,7 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { case calculator.Type: if bolus := bsonData["bolus"]; bolus != nil { if bolusID, ok := bolus.(string); ok { - log.Printf("## setting the %v bolus reference %v", calculator.Type, bolusID) + // Set so we can validate the reference is valid bsonData["bolusId"] = bolusID delete(bsonData, "bolus") } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index f69bc54495..fa94ebb392 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -277,6 +277,17 @@ var _ = Describe("back-37", func() { Expect(deviceEventData["statusId"]).To(Equal("some-status-id")) }) }) + Context("wizard datum with bolus string", func() { + It("should convert to bolusId for datum validation", func() { + wizardBSON := getBSONData(test.WizardTandem) + Expect(wizardBSON["bolus"]).ToNot(BeNil()) + expectedBolusID := wizardBSON["bolus"].(string) + err := utils.ApplyBaseChanges(wizardBSON, calculator.Type) + Expect(err).To(BeNil()) + Expect(wizardBSON["bolus"]).To(BeNil()) + Expect(wizardBSON["bolusId"]).To(Equal(expectedBolusID)) + }) + }) Context("datum with string payload", func() { var datumWithPayload primitive.M var datumType string @@ -322,36 +333,6 @@ var _ = Describe("back-37", func() { datumType = fmt.Sprintf("%v", datumWithAnnotation["type"]) }) - It("should do nothing when value is already correct", func() { - Expect(datumWithAnnotation["annotations"]).To(Equal(*annotations)) - err := utils.ApplyBaseChanges(datumWithAnnotation, datumType) - Expect(err).To(BeNil()) - Expect(datumWithAnnotation["annotations"]).To(Equal(*annotations)) - }) - It("should update the annotations when it is a string", func() { - datumWithAnnotation["annotations"] = `[{"code":"bg/out-of-range","threshold":40,"value":"low"}]` - err := utils.ApplyBaseChanges(datumWithAnnotation, datumType) - Expect(err).To(BeNil()) - Expect(datumWithAnnotation["annotations"]).To(Equal(&metadata.MetadataArray{ - &metadata.Metadata{ - "code": "bg/out-of-range", - "threshold": float64(40), - "value": "low", - }, - })) - }) - }) - Context("datum with string annotations", func() { - var datumWithAnnotation primitive.M - var annotations *metadata.MetadataArray - var datumType string - BeforeEach(func() { - datumWithAnnotation = getBSONData(pumpSettingsDatum) - annotations = metadataTest.RandomMetadataArray() - datumWithAnnotation["annotations"] = *annotations - datumType = fmt.Sprintf("%v", datumWithAnnotation["type"]) - }) - It("should do nothing when value is already correct", func() { Expect(datumWithAnnotation["annotations"]).To(Equal(*annotations)) err := utils.ApplyBaseChanges(datumWithAnnotation, datumType) @@ -384,21 +365,17 @@ var _ = Describe("back-37", func() { return rawObject } - var incomingObject map[string]interface{} - var datumObject bson.M - - BeforeEach(func() { - datumObject = getBSONData(test.AutomatedBasalTandem) - incomingObject = getRawData(test.AutomatedBasalTandem) - }) - It("has no difference", func() { + datumObject := getBSONData(test.AutomatedBasalTandem) + incomingObject := getRawData(test.AutomatedBasalTandem) diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) Expect(err).To(BeNil()) Expect(diff).ToNot(BeNil()) Expect(diff).To(Equal([]bson.M{})) }) It("set for missing properties", func() { + datumObject := getBSONData(test.AutomatedBasalTandem) + incomingObject := getRawData(test.AutomatedBasalTandem) delete(incomingObject, "deliveryType") diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) Expect(err).To(BeNil()) @@ -418,17 +395,39 @@ var _ = Describe("back-37", func() { })) }) It("unset for unwanted properties", func() { + datumObject := getBSONData(test.AutomatedBasalTandem) + incomingObject := getRawData(test.AutomatedBasalTandem) incomingObject["random"] = map[string]interface{}{"extra": true} diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) Expect(err).To(BeNil()) Expect(diff).To(Equal([]bson.M{{"$unset": bson.M{"random": ""}}})) }) It("no difference when inner payload changes", func() { + datumObject := getBSONData(test.AutomatedBasalTandem) + incomingObject := getRawData(test.AutomatedBasalTandem) datumObject["payload"] = map[string]interface{}{"stuff": true} diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) Expect(err).To(BeNil()) Expect(diff).To(Equal([]bson.M{})) }) + + It("should convert to bolusId for datum validation", func() { + datumObject := getBSONData(test.WizardTandem) + + err := utils.ApplyBaseChanges(datumObject, calculator.Type) + + incomingObject := getRawData(datumObject) + Expect(err).To(BeNil()) + Expect(datumObject["bolusId"]).ToNot(BeNil()) + Expect(datumObject["bolus"]).To(BeNil()) + Expect(incomingObject["bolusId"]).ToNot(BeNil()) + Expect(incomingObject["bolus"]).To(BeNil()) + calcID := fmt.Sprintf("%v", datumObject["_id"]) + diff, err := utils.GetDatumChanges(calcID, datumObject, incomingObject) + Expect(err).To(BeNil()) + Expect(diff).To(Equal([]bson.M{})) + }) + }) }) }) From 53f032123b04b26d9a3e7b20233859719b00d239 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 23 Feb 2024 12:52:54 +1300 Subject: [PATCH 235/413] fixes for pathing --- .../utils/utils.go | 26 +++----- .../utils/utils_test.go | 59 ++++++++++++++----- 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 69c56d0fc0..8dee7fd18d 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -54,13 +54,14 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { switch dataType { case pump.Type: - //mis-named boluses + if boluses := bsonData["bolus"]; boluses != nil { + //fix mis-named boluses bsonData["boluses"] = boluses - //TODO delete from mongo delete(bsonData, "bolus") } if schedules := bsonData["sleepSchedules"]; schedules != nil { + //fix sleepSchedules to be a map scheduleNames := map[int]string{0: "1", 1: "2"} sleepScheduleMap := pump.SleepScheduleMap{} dataBytes, err := json.Marshal(schedules) @@ -88,6 +89,7 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { } case selfmonitored.Type, ketone.Type, continuous.Type: + // fix BG Precision units := fmt.Sprintf("%v", bsonData["units"]) if units == glucose.MmolL || units == glucose.Mmoll { if val := getBGValuePrecision(bsonData["value"]); val != nil { @@ -112,9 +114,8 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { } case calculator.Type: if bolus := bsonData["bolus"]; bolus != nil { - if bolusID, ok := bolus.(string); ok { - // Set so we can validate the reference is valid - bsonData["bolusId"] = bolusID + if _, ok := bolus.(string); ok { + //if the bolus is a string reference then its ok so leave as is delete(bsonData, "bolus") } } @@ -294,23 +295,12 @@ func GetDatumChanges(id string, datum interface{}, original map[string]interface set := bson.M{} unset := bson.M{} - // ["path","to","change"] - // {path: {to: {change: true}}} - var getValue = func(path []string, val interface{}) interface{} { - if len(path) == 1 { - return val - } else if len(path) == 2 { - return bson.M{path[1]: val} - } - return bson.M{path[1]: bson.M{path[2]: val}} - } - for _, change := range changelog.FilterOut([]string{"payload"}) { switch change.Type { case diff.CREATE, diff.UPDATE: - set[change.Path[0]] = getValue(change.Path, change.To) + set[strings.Join(change.Path, ".")] = change.To case diff.DELETE: - unset[change.Path[0]] = getValue(change.Path, "") + unset[strings.Join(change.Path, ".")] = "" } } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index fa94ebb392..8ea354e586 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -3,6 +3,7 @@ package utils_test import ( "encoding/json" "fmt" + "log" "strings" "time" @@ -281,11 +282,9 @@ var _ = Describe("back-37", func() { It("should convert to bolusId for datum validation", func() { wizardBSON := getBSONData(test.WizardTandem) Expect(wizardBSON["bolus"]).ToNot(BeNil()) - expectedBolusID := wizardBSON["bolus"].(string) err := utils.ApplyBaseChanges(wizardBSON, calculator.Type) Expect(err).To(BeNil()) Expect(wizardBSON["bolus"]).To(BeNil()) - Expect(wizardBSON["bolusId"]).To(Equal(expectedBolusID)) }) }) Context("datum with string payload", func() { @@ -402,6 +401,44 @@ var _ = Describe("back-37", func() { Expect(err).To(BeNil()) Expect(diff).To(Equal([]bson.M{{"$unset": bson.M{"random": ""}}})) }) + It("allow for removing deeply nested properties", func() { + datumObject := getBSONData(test.AutomatedBasalTandem) + incomingObject := getRawData(test.AutomatedBasalTandem) + incomingObject["lots"] = map[string]interface{}{ + "of": map[string]interface{}{ + "things": map[string]interface{}{ + "go": map[string]interface{}{ + "here": true}}}} + diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) + Expect(err).To(BeNil()) + Expect(diff).To(Equal([]bson.M{{"$unset": bson.M{"lots": ""}}})) + }) + It("allow for updating nested array properties", func() { + datumObject := getBSONData(test.PumpSettingsTandem) + incomingObject := getRawData(test.PumpSettingsTandem) + + datumObject["insulinSensitivities"] = map[string]interface{}{ + "Simple": []map[string]interface{}{ + {"amount": 1.2, "start": 0}, + {"amount": 2.6, "start": 46800000}, + }, + "Standard": []map[string]interface{}{ + {"amount": 2.7753739955227665, "start": 1000}, + {"amount": 2.7753739955227665, "start": 46800000}, + }, + } + + diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) + log.Printf("err %v", err) + Expect(err).To(BeNil()) + Expect(diff).To(Equal([]bson.M{ + {"$set": bson.M{ + "insulinSensitivities.Simple.0.amount": 1.2, + "insulinSensitivities.Simple.1.amount": 2.6, + "insulinSensitivities.Standard.0.start": float64(1000), + }}, + })) + }) It("no difference when inner payload changes", func() { datumObject := getBSONData(test.AutomatedBasalTandem) incomingObject := getRawData(test.AutomatedBasalTandem) @@ -412,20 +449,12 @@ var _ = Describe("back-37", func() { }) It("should convert to bolusId for datum validation", func() { - datumObject := getBSONData(test.WizardTandem) - - err := utils.ApplyBaseChanges(datumObject, calculator.Type) - - incomingObject := getRawData(datumObject) - Expect(err).To(BeNil()) - Expect(datumObject["bolusId"]).ToNot(BeNil()) - Expect(datumObject["bolus"]).To(BeNil()) - Expect(incomingObject["bolusId"]).ToNot(BeNil()) - Expect(incomingObject["bolus"]).To(BeNil()) - calcID := fmt.Sprintf("%v", datumObject["_id"]) - diff, err := utils.GetDatumChanges(calcID, datumObject, incomingObject) + bsonData := getBSONData(test.WizardTandem) + datumID := fmt.Sprintf("%v", bsonData["_id"]) + datumType := fmt.Sprintf("%v", bsonData["type"]) + diff, err := utils.ProcessDatum(datumID, datumType, bsonData) Expect(err).To(BeNil()) - Expect(diff).To(Equal([]bson.M{})) + Expect(diff[1]["$unset"]).ShouldNot(HaveKey("bolusId")) }) }) From b35d332dd1510ed42b88f1ab6d44fb01c0bbd74c Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 27 Feb 2024 14:47:25 +1300 Subject: [PATCH 236/413] update has both an apply and revert --- .../jellyfish_migration.go | 5 +- .../utils/migrationUtil.go | 50 +++-- .../utils/utils.go | 173 +++++++++++++++--- .../utils/utils_test.go | 85 ++++++--- 4 files changed, 247 insertions(+), 66 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 8bd5d38b91..ebc122a50c 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -225,6 +225,7 @@ func (m *Migration) fetchAndProcess() bool { return false } itemID := fmt.Sprintf("%v", item["_id"]) + userID := fmt.Sprintf("%v", item["_userId"]) itemType := fmt.Sprintf("%v", item["type"]) updates, err := utils.ProcessDatum(itemID, itemType, item) if err != nil { @@ -233,8 +234,10 @@ func (m *Migration) fetchAndProcess() bool { m.migrationUtil.SetUpdates(utils.UpdateData{ Filter: bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}, ItemID: itemID, + UserID: userID, ItemType: itemType, - Updates: updates, + Apply: updates, + Revert: updates, }) } m.migrationUtil.SetLastProcessed(itemID) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 3b717bc0d8..f7b4f0a6b8 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -8,6 +8,7 @@ import ( "log" "math" "os" + "path/filepath" "strings" "time" @@ -53,8 +54,10 @@ type migrationUtil struct { type UpdateData struct { Filter interface{} `json:"-"` ItemID string `json:"_id"` + UserID string `json:"_userId"` ItemType string `json:"-"` - Updates []bson.M `json:"diff"` + Apply []bson.M `json:"apply"` + Revert []bson.M `json:"revert"` } type ErrorData struct { @@ -141,8 +144,6 @@ func (m *migrationUtil) capReached() bool { func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func() bool) error { for fetchAndUpdateFn() { if err := m.writeUpdates(ctx, dataC); err != nil { - log.Printf("failed writing batch: %s", err) - // dump errors first m.writeErrors(nil) return err } @@ -158,7 +159,7 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe func (m *migrationUtil) SetUpdates(data UpdateData) { m.groupedDiffs[data.ItemType] = append(m.groupedDiffs[data.ItemType], data) - for _, u := range data.Updates { + for _, u := range data.Apply { updateOp := mongo.NewUpdateOneModel() updateOp.Filter = data.Filter updateOp.SetUpdate(u) @@ -170,9 +171,33 @@ func (m *migrationUtil) SetLastProcessed(lastID string) { m.lastUpdatedId = lastID } +func createFile(fileType string, dataGroup string, logName string) (*os.File, error) { + timestamp := strings.Replace(time.Now().Truncate(time.Microsecond*15).Format(time.Stamp), " ", "-", -1) + var err error + if fileType == "" { + errors.Join(err, errors.New("missing file type")) + } + if dataGroup == "" { + errors.Join(err, errors.New("missing data group")) + } + if logName == "" { + errors.Join(err, errors.New("missing log group")) + } + if err != nil { + return nil, err + } + logName = fmt.Sprintf(logName, dataGroup) + logPath := filepath.Join(".", fileType, timestamp) + + err = os.MkdirAll(logPath, os.ModePerm) + if err != nil { + return nil, err + } + return os.OpenFile(logPath+logName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) +} + func (m *migrationUtil) writeErrors(groupLimit *int) { - timestamp := strings.Replace(time.Now().Format(time.Stamp), " ", "-", -1) - logName := "logs/error.log" + for group, errors := range m.groupedErrors { if groupLimit != nil { @@ -180,15 +205,13 @@ func (m *migrationUtil) writeErrors(groupLimit *int) { continue } } - if group != "" { - logName = fmt.Sprintf("logs/error_%s_%s.log", group, timestamp) - } - f, err := os.OpenFile(logName, - os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + + f, err := createFile("logs", group, "error_%s.log") if err != nil { log.Println(err) os.Exit(1) } + defer f.Close() for _, data := range errors { @@ -204,16 +227,13 @@ func (m *migrationUtil) writeErrors(groupLimit *int) { } func (m *migrationUtil) writeDiff(groupLimit *int) { - timestamp := strings.Replace(time.Now().Format(time.Stamp), " ", "-", -1) for group, diffs := range m.groupedDiffs { if groupLimit != nil { if len(diffs) < *groupLimit { continue } } - logName := fmt.Sprintf("updates/diff_%s_%s.log", group, timestamp) - f, err := os.OpenFile(logName, - os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + f, err := createFile("updates", group, "diff_%s.json") if err != nil { log.Println(err) os.Exit(1) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 8dee7fd18d..17e44d8822 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -34,6 +34,7 @@ import ( structureValidator "github.com/tidepool-org/platform/structure/validator" ) +// NOTE: required to ensure consitent precision of bg values in the platform func getBGValuePrecision(val interface{}) *float64 { floatStr := fmt.Sprintf("%v", val) floatParts := strings.Split(floatStr, ".") @@ -50,18 +51,55 @@ func getBGValuePrecision(val interface{}) *float64 { return nil } +func getTarget(bgTarget interface{}) (*glucose.Target, error) { + dataBytes, err := json.Marshal(bgTarget) + if err != nil { + return nil, err + } + var target glucose.Target + err = json.Unmarshal(dataBytes, &target) + if err != nil { + return nil, errorsP.Newf("bgTarget %s", string(dataBytes)) + } + return &target, nil +} + +func setGlucoseTargetPrecision(target *glucose.Target) *glucose.Target { + if bg := target.High; bg != nil { + if val := getBGValuePrecision(bg); val != nil { + target.High = val + } + } + if bg := target.Low; bg != nil { + if val := getBGValuePrecision(bg); val != nil { + target.Low = val + } + } + if bg := target.Range; bg != nil { + if val := getBGValuePrecision(bg); val != nil { + target.Range = val + } + } + if low := target.Target; low != nil { + if val := getBGValuePrecision(low); val != nil { + target.Target = val + } + } + return target +} + func ApplyBaseChanges(bsonData bson.M, dataType string) error { switch dataType { case pump.Type: if boluses := bsonData["bolus"]; boluses != nil { - //fix mis-named boluses + // NOTE: fix mis-named boluses which were saved in jellyfish as a `bolus` bsonData["boluses"] = boluses delete(bsonData, "bolus") } if schedules := bsonData["sleepSchedules"]; schedules != nil { - //fix sleepSchedules to be a map + // NOTE: this is to fix sleepSchedules so they are in the required map format scheduleNames := map[int]string{0: "1", 1: "2"} sleepScheduleMap := pump.SleepScheduleMap{} dataBytes, err := json.Marshal(schedules) @@ -87,9 +125,75 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { } bsonData["sleepSchedules"] = &sleepScheduleMap } + if bgTargetPhysicalActivity := bsonData["bgTargetPhysicalActivity"]; bgTargetPhysicalActivity != nil { + target, err := getTarget(bgTargetPhysicalActivity) + if err != nil { + return err + } + bsonData["bgTargetPhysicalActivity"] = setGlucoseTargetPrecision(target) + } + if bgTargetPreprandial := bsonData["bgTargetPreprandial"]; bgTargetPreprandial != nil { + target, err := getTarget(bgTargetPreprandial) + if err != nil { + return err + } + bsonData["bgTargetPreprandial"] = setGlucoseTargetPrecision(target) + } + if bgTarget := bsonData["bgTarget"]; bgTarget != nil { + + var bgTargetStartArry pump.BloodGlucoseTargetStartArray + + dataBytes, err := json.Marshal(bgTarget) + if err != nil { + return err + } + err = json.Unmarshal(dataBytes, &bgTargetStartArry) + if err != nil { + return errorsP.Newf("bgTarget %s", string(dataBytes)) + } + + for _, item := range bgTargetStartArry { + item.Target = *setGlucoseTargetPrecision(&item.Target) + } + + bsonData["bgTarget"] = &bgTargetStartArry + } + if bgTargets := bsonData["bgTargets"]; bgTargets != nil { + var data pump.BloodGlucoseTargetStartArrayMap + dataBytes, err := json.Marshal(bgTargets) + if err != nil { + return err + } + err = json.Unmarshal(dataBytes, &data) + if err != nil { + return err + } + for i, d := range data { + for x, t := range *d { + t.Target = *setGlucoseTargetPrecision(&t.Target) + (*d)[x] = t + } + data[i] = d + } + bsonData["bgTargets"] = data + } + if overridePresets := bsonData["overridePresets"]; overridePresets != nil { + var overridePresetMap pump.OverridePresetMap + dataBytes, err := json.Marshal(overridePresets) + if err != nil { + return err + } + err = json.Unmarshal(dataBytes, &overridePresetMap) + if err != nil { + return err + } + for i, p := range overridePresetMap { + overridePresetMap[i].BloodGlucoseTarget = setGlucoseTargetPrecision(p.BloodGlucoseTarget) + } + bsonData["overridePresets"] = &overridePresetMap + } case selfmonitored.Type, ketone.Type, continuous.Type: - // fix BG Precision units := fmt.Sprintf("%v", bsonData["units"]) if units == glucose.MmolL || units == glucose.Mmoll { if val := getBGValuePrecision(bsonData["value"]); val != nil { @@ -114,15 +218,28 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { } case calculator.Type: if bolus := bsonData["bolus"]; bolus != nil { + // NOTE: we are doing this to ensure that the `bolus` is just a string reference if _, ok := bolus.(string); ok { - //if the bolus is a string reference then its ok so leave as is delete(bsonData, "bolus") } } + if bgTarget := bsonData["bgTarget"]; bgTarget != nil { + target, err := getTarget(bgTarget) + if err != nil { + return err + } + bsonData["bgTarget"] = setGlucoseTargetPrecision(target) + } + if bgInput := bsonData["bgInput"]; bgInput != nil { + if val := getBGValuePrecision(bgInput); val != nil { + bsonData["bgInput"] = val + } + } case device.Type: subType := fmt.Sprintf("%v", bsonData["subType"]) switch subType { case reservoirchange.SubType, alarm.SubType: + // NOTE: we are doing this to ensure that the `status` is just a string reference and then setting the `statusId` with it if status := bsonData["status"]; status != nil { if statusID, ok := status.(string); ok { bsonData["statusId"] = statusID @@ -249,16 +366,16 @@ func BuildPlatformDatum(objID string, objType string, objectData map[string]inte return datum, nil } -func GetDatumChanges(id string, datum interface{}, original map[string]interface{}) ([]bson.M, error) { +func GetDatumChanges(id string, datum interface{}, original map[string]interface{}) ([]bson.M, []bson.M, error) { outgoingJSONData, err := json.Marshal(datum) if err != nil { - return nil, err + return nil, nil, err } processedObject := map[string]interface{}{} if err := json.Unmarshal(outgoingJSONData, &processedObject); err != nil { - return nil, err + return nil, nil, err } if deduplicator := processedObject["deduplicator"]; deduplicator != nil { @@ -289,29 +406,43 @@ func GetDatumChanges(id string, datum interface{}, original map[string]interface changelog, err := diff.Diff(original, processedObject, diff.StructMapKeySupport()) if err != nil { - return nil, err + return nil, nil, err } - set := bson.M{} - unset := bson.M{} + applySet := bson.M{} + revertSet := bson.M{} + applyUnset := bson.M{} + revertUnset := bson.M{} for _, change := range changelog.FilterOut([]string{"payload"}) { switch change.Type { - case diff.CREATE, diff.UPDATE: - set[strings.Join(change.Path, ".")] = change.To + case diff.CREATE: + applySet[strings.Join(change.Path, ".")] = change.To + revertUnset[strings.Join(change.Path, ".")] = "" + case diff.UPDATE: + applySet[strings.Join(change.Path, ".")] = change.To + revertSet[strings.Join(change.Path, ".")] = change.From case diff.DELETE: - unset[strings.Join(change.Path, ".")] = "" + applyUnset[strings.Join(change.Path, ".")] = "" + revertSet[strings.Join(change.Path, ".")] = change.From } } - difference := []bson.M{} - if len(set) > 0 { - difference = append(difference, bson.M{"$set": set}) + apply := []bson.M{} + revert := []bson.M{} + if len(applySet) > 0 { + apply = append(apply, bson.M{"$set": applySet}) + } + if len(revertUnset) > 0 { + revert = append(revert, bson.M{"$unset": revertUnset}) + } + if len(applyUnset) > 0 { + apply = append(apply, bson.M{"$unset": applyUnset}) } - if len(unset) > 0 { - difference = append(difference, bson.M{"$unset": unset}) + if len(revertSet) > 0 { + revert = append(revert, bson.M{"$set": revertSet}) } - return difference, nil + return apply, revert, nil } func ProcessDatum(dataID string, dataType string, bsonData bson.M) ([]bson.M, error) { @@ -334,9 +465,9 @@ func ProcessDatum(dataID string, dataType string, bsonData bson.M) ([]bson.M, er return nil, err } - updates, err := GetDatumChanges(dataID, datum, ojbData) + apply, _, err := GetDatumChanges(dataID, datum, ojbData) if err != nil { return nil, err } - return updates, nil + return apply, nil } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 8ea354e586..bbd0004f50 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -124,7 +124,6 @@ var _ = Describe("back-37", func() { var _ = Describe("ApplyBaseChanges", func() { const expectedID = "some-id" - var pumpSettingsDatum *pump.Pump BeforeEach(func() { @@ -261,7 +260,7 @@ var _ = Describe("back-37", func() { Expect(cbgData["value"]).To(Equal(4.88466)) }) }) - Context("reservoirChange deviceEvent datum status string", func() { + Context("reservoirChange deviceEvent datum with status string", func() { var newReservoirChange = func() *reservoirchange.ReservoirChange { datum := reservoirchange.New() datum.Device = *dataTypesDeviceTest.RandomDevice() @@ -367,51 +366,60 @@ var _ = Describe("back-37", func() { It("has no difference", func() { datumObject := getBSONData(test.AutomatedBasalTandem) incomingObject := getRawData(test.AutomatedBasalTandem) - diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) + apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) Expect(err).To(BeNil()) - Expect(diff).ToNot(BeNil()) - Expect(diff).To(Equal([]bson.M{})) + Expect(apply).ToNot(BeNil()) + Expect(apply).To(Equal([]bson.M{})) + Expect(revert).ToNot(BeNil()) + Expect(revert).To(Equal([]bson.M{})) }) It("set for missing properties", func() { datumObject := getBSONData(test.AutomatedBasalTandem) incomingObject := getRawData(test.AutomatedBasalTandem) delete(incomingObject, "deliveryType") - diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) + apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) Expect(err).To(BeNil()) - Expect(diff).To(Equal([]bson.M{{"$set": bson.M{"deliveryType": "automated"}}})) + Expect(apply).To(Equal([]bson.M{{"$set": bson.M{"deliveryType": "automated"}}})) + Expect(revert).To(Equal([]bson.M{{"$unset": bson.M{"deliveryType": ""}}})) }) It("set _deduplicator correctly", func() { calcData, _ := datumSetup(test.WizardTandem) id := fmt.Sprintf("%v", calcData["_id"]) datum, _ := utils.BuildPlatformDatum(id, calculator.Type, calcData) - diff, err := utils.GetDatumChanges(id, datum, calcData) + apply, revert, err := utils.GetDatumChanges(id, datum, calcData) Expect(err).To(BeNil()) - Expect(diff[0]["$set"]).To( - Equal( - bson.M{ - "time": "2022-06-21T22:40:07.732Z", - "_deduplicator": map[string]interface{}{"hash": "o6ybZQtDZ95FvuV0zYGphri2SIGesbLCbkHxc1wbbEE="}, - })) + Expect(len(apply)).To(Equal(2)) + Expect(apply[0]["$set"]).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "o6ybZQtDZ95FvuV0zYGphri2SIGesbLCbkHxc1wbbEE="})) + Expect(len(revert)).To(Equal(2)) + Expect(revert[0]).Should(HaveKeyWithValue("$unset", bson.M{"_deduplicator": ""})) }) It("unset for unwanted properties", func() { datumObject := getBSONData(test.AutomatedBasalTandem) incomingObject := getRawData(test.AutomatedBasalTandem) incomingObject["random"] = map[string]interface{}{"extra": true} - diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) + apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) Expect(err).To(BeNil()) - Expect(diff).To(Equal([]bson.M{{"$unset": bson.M{"random": ""}}})) + Expect(len(apply)).To(Equal(1)) + Expect(apply[0]).Should(HaveKeyWithValue("$unset", bson.M{"random": ""})) + Expect(len(revert)).To(Equal(1)) + Expect(revert[0]).Should(HaveKeyWithValue("$set", bson.M{"random": map[string]interface{}{"extra": true}})) }) It("allow for removing deeply nested properties", func() { datumObject := getBSONData(test.AutomatedBasalTandem) incomingObject := getRawData(test.AutomatedBasalTandem) - incomingObject["lots"] = map[string]interface{}{ + + ofThings := map[string]interface{}{ "of": map[string]interface{}{ "things": map[string]interface{}{ "go": map[string]interface{}{ "here": true}}}} - diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) + incomingObject["lots"] = ofThings + apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) Expect(err).To(BeNil()) - Expect(diff).To(Equal([]bson.M{{"$unset": bson.M{"lots": ""}}})) + Expect(len(apply)).To(Equal(1)) + Expect(apply[0]).Should(HaveKeyWithValue("$unset", bson.M{"lots": ""})) + Expect(len(revert)).To(Equal(1)) + Expect(revert[0]).Should(HaveKeyWithValue("$set", bson.M{"lots": ofThings})) }) It("allow for updating nested array properties", func() { datumObject := getBSONData(test.PumpSettingsTandem) @@ -428,33 +436,52 @@ var _ = Describe("back-37", func() { }, } - diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) + apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) log.Printf("err %v", err) Expect(err).To(BeNil()) - Expect(diff).To(Equal([]bson.M{ - {"$set": bson.M{ - "insulinSensitivities.Simple.0.amount": 1.2, - "insulinSensitivities.Simple.1.amount": 2.6, - "insulinSensitivities.Standard.0.start": float64(1000), - }}, + Expect(len(apply)).To(Equal(1)) + Expect(apply[0]).Should(HaveKeyWithValue("$set", bson.M{ + "insulinSensitivities.Simple.0.amount": 1.2, + "insulinSensitivities.Simple.1.amount": 2.6, + "insulinSensitivities.Standard.0.start": float64(1000), + })) + Expect(len(revert)).To(Equal(1)) + Expect(revert[0]).Should(HaveKeyWithValue("$set", bson.M{ + "insulinSensitivities.Simple.0.amount": 2.7753739955227665, + "insulinSensitivities.Simple.1.amount": 2.7753739955227665, + "insulinSensitivities.Standard.0.start": float64(0), })) }) It("no difference when inner payload changes", func() { datumObject := getBSONData(test.AutomatedBasalTandem) incomingObject := getRawData(test.AutomatedBasalTandem) datumObject["payload"] = map[string]interface{}{"stuff": true} - diff, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) + apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) Expect(err).To(BeNil()) - Expect(diff).To(Equal([]bson.M{})) + Expect(apply).To(Equal([]bson.M{})) + Expect(revert).To(Equal([]bson.M{})) }) It("should convert to bolusId for datum validation", func() { bsonData := getBSONData(test.WizardTandem) datumID := fmt.Sprintf("%v", bsonData["_id"]) datumType := fmt.Sprintf("%v", bsonData["type"]) + apply, err := utils.ProcessDatum(datumID, datumType, bsonData) + Expect(err).To(BeNil()) + Expect(apply[1]["$unset"]).ShouldNot(HaveKey("bolusId")) + }) + + It("should update all bgTraget values", func() { + bsonData := getBSONData(test.PumpSettingsCarelink) + datumID := fmt.Sprintf("%v", bsonData["_id"]) + datumType := fmt.Sprintf("%v", bsonData["type"]) diff, err := utils.ProcessDatum(datumID, datumType, bsonData) Expect(err).To(BeNil()) - Expect(diff[1]["$unset"]).ShouldNot(HaveKey("bolusId")) + Expect(diff[0]["$set"]).ToNot(BeNil()) + Expect(len(diff)).To(Equal(2)) + Expect(diff[0]["$set"]).Should(HaveKeyWithValue("units.bg", "mmol/L")) + Expect(diff[0]["$set"]).Should(HaveKeyWithValue("bgTarget.0.target", float64(0.30811))) + Expect(diff[0]["$set"]).Should(HaveKeyWithValue("bgTarget.1.target", float64(0.30811))) }) }) From f8a5fb304d65c43906f615cc138e9da2b4c72591 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 27 Feb 2024 15:23:04 +1300 Subject: [PATCH 237/413] fix log paths --- .../utils/migrationUtil.go | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index f7b4f0a6b8..d78c243aa0 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -172,7 +172,9 @@ func (m *migrationUtil) SetLastProcessed(lastID string) { } func createFile(fileType string, dataGroup string, logName string) (*os.File, error) { - timestamp := strings.Replace(time.Now().Truncate(time.Microsecond*15).Format(time.Stamp), " ", "-", -1) + datetime := time.Now().Round(15 * time.Minute) + timestamp := strings.Replace(datetime.Format(time.Stamp), " ", "-", -1) + datestamp := strings.Replace(datetime.Format(time.DateOnly), " ", "-", -1) var err error if fileType == "" { errors.Join(err, errors.New("missing file type")) @@ -187,41 +189,34 @@ func createFile(fileType string, dataGroup string, logName string) (*os.File, er return nil, err } logName = fmt.Sprintf(logName, dataGroup) - logPath := filepath.Join(".", fileType, timestamp) + logPath := filepath.Join(".", fileType, datestamp, timestamp) err = os.MkdirAll(logPath, os.ModePerm) if err != nil { return nil, err } - return os.OpenFile(logPath+logName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + return os.OpenFile(logPath+"/"+logName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) } func (m *migrationUtil) writeErrors(groupLimit *int) { - for group, errors := range m.groupedErrors { - if groupLimit != nil { if len(errors) < *groupLimit { continue } } - f, err := createFile("logs", group, "error_%s.log") if err != nil { log.Println(err) os.Exit(1) } - defer f.Close() - - for _, data := range errors { - errorJSON, err := json.Marshal(data) - if err != nil { - log.Println(err) - os.Exit(1) - } - f.WriteString(string(errorJSON) + "\n") + errorsJSON, err := json.Marshal(errors) + if err != nil { + log.Println(err) + os.Exit(1) } + f.WriteString(string(errorsJSON) + "\n") m.groupedErrors[group] = []ErrorData{} } } @@ -239,14 +234,12 @@ func (m *migrationUtil) writeDiff(groupLimit *int) { os.Exit(1) } defer f.Close() - for _, data := range diffs { - diffJSON, err := json.Marshal(data) - if err != nil { - log.Println(err) - os.Exit(1) - } - f.WriteString(string(diffJSON) + "\n") + diffsJSON, err := json.Marshal(diffs) + if err != nil { + log.Println(err) + os.Exit(1) } + f.WriteString(string(diffsJSON) + "\n") m.groupedDiffs[group] = []UpdateData{} } } From 189441f34d1eb3e3abd1cc588642c33f8ff2d13f Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 27 Feb 2024 15:37:58 +1300 Subject: [PATCH 238/413] write line by line --- .../utils/migrationUtil.go | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index d78c243aa0..56ed8629bd 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -173,8 +173,8 @@ func (m *migrationUtil) SetLastProcessed(lastID string) { func createFile(fileType string, dataGroup string, logName string) (*os.File, error) { datetime := time.Now().Round(15 * time.Minute) - timestamp := strings.Replace(datetime.Format(time.Stamp), " ", "-", -1) - datestamp := strings.Replace(datetime.Format(time.DateOnly), " ", "-", -1) + timestamp := strings.Replace(datetime.Format(time.TimeOnly), ":", "_", -1) + datestamp := datetime.Format(time.DateOnly) var err error if fileType == "" { errors.Join(err, errors.New("missing file type")) @@ -211,12 +211,14 @@ func (m *migrationUtil) writeErrors(groupLimit *int) { os.Exit(1) } defer f.Close() - errorsJSON, err := json.Marshal(errors) - if err != nil { - log.Println(err) - os.Exit(1) + for _, data := range errors { + errJSON, err := json.Marshal(data) + if err != nil { + log.Println(err) + os.Exit(1) + } + f.WriteString(string(errJSON) + ",\n") } - f.WriteString(string(errorsJSON) + "\n") m.groupedErrors[group] = []ErrorData{} } } @@ -234,12 +236,14 @@ func (m *migrationUtil) writeDiff(groupLimit *int) { os.Exit(1) } defer f.Close() - diffsJSON, err := json.Marshal(diffs) - if err != nil { - log.Println(err) - os.Exit(1) + for _, data := range diffs { + diffJSON, err := json.Marshal(data) + if err != nil { + log.Println(err) + os.Exit(1) + } + f.WriteString(string(diffJSON) + ",\n") } - f.WriteString(string(diffsJSON) + "\n") m.groupedDiffs[group] = []UpdateData{} } } From 5cb3cba81fff7e11b329a70712e91bc82c2400b4 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 28 Feb 2024 14:48:40 +1300 Subject: [PATCH 239/413] set revert for logging --- .../20231128_jellyfish_migration/jellyfish_migration.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index ebc122a50c..c674beb2c0 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -227,7 +227,7 @@ func (m *Migration) fetchAndProcess() bool { itemID := fmt.Sprintf("%v", item["_id"]) userID := fmt.Sprintf("%v", item["_userId"]) itemType := fmt.Sprintf("%v", item["type"]) - updates, err := utils.ProcessDatum(itemID, itemType, item) + updates, revert, err := utils.ProcessDatum(itemID, itemType, item) if err != nil { m.migrationUtil.OnError(utils.ErrorData{Error: err, ItemID: itemID, ItemType: itemType}) } else if len(updates) > 0 { @@ -237,7 +237,7 @@ func (m *Migration) fetchAndProcess() bool { UserID: userID, ItemType: itemType, Apply: updates, - Revert: updates, + Revert: revert, }) } m.migrationUtil.SetLastProcessed(itemID) From 4249efb4bcd4c11038cc9dc56224b9abf8d55703 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 28 Feb 2024 14:49:23 +1300 Subject: [PATCH 240/413] attempt to get vaild bg updates --- .../utils/test/data.go | 34 + .../utils/utils.go | 312 +++--- .../utils/utils_test.go | 973 ++++++++++-------- 3 files changed, 733 insertions(+), 586 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go index 0662628565..6e4671e801 100644 --- a/migrations/20231128_jellyfish_migration/utils/test/data.go +++ b/migrations/20231128_jellyfish_migration/utils/test/data.go @@ -153,6 +153,39 @@ func omnipodPumpSettingsDatum() map[string]interface{} { return datum } +func omnipodPumpSettingsDatumTargetSet() map[string]interface{} { + + datum := base("InsOmn-837268") + datum["type"] = "pumpSettings" + datum["activeSchedule"] = "Mine-2016" + datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mg/dL"} + datum["basalSchedules"] = map[string]interface{}{ + "Mine-2016": []map[string]interface{}{ + {"rate": 0.5, "start": 0}, + {"rate": 1.35, "start": 55800000}, + }, + "camp 2015": []map[string]interface{}{ + {"rate": 0.5, "start": 0}, + {"rate": 1.35, "start": 55800000}, + }, + "weekend b": []map[string]interface{}{}, + } + datum["carbRatio"] = []map[string]interface{}{ + {"amount": 10, "start": 0}, + {"amount": 10, "start": 32400000}, + } + datum["insulinSensitivity"] = []map[string]interface{}{ + {"amount": 2.7753739955227665, "start": 0}, + {"amount": 2.7753739955227665, "start": 46800000}, + } + + datum["bgTarget"] = []map[string]interface{}{ + {"target": 5.550747991045533, "start": 0, "high": 7.2159723883591935}, + {"target": 5.550747991045533, "start": 46800000, "high": 7.2159723883591935}, + } + return datum +} + func tandemAutomatedBasalDatum() map[string]interface{} { datum := base("tandemCIQ1111111111111") datum["type"] = "basal" @@ -242,6 +275,7 @@ var CBGDexcomG5MobDatum = dexG5MobDatum() var PumpSettingsTandem = tandemPumpSettingsDatum() var PumpSettingsCarelink = carelinkPumpSettings() var PumpSettingsOmnipod = omnipodPumpSettingsDatum() +var PumpSettingsOmnipodBGTargetCorrect = omnipodPumpSettingsDatumTargetSet() var AutomatedBasalTandem = tandemAutomatedBasalDatum() var WizardTandem = tandemWizardDatum() var ReservoirChange = reservoirChangeDeviceEventDatum() diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 17e44d8822..54db23736c 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -3,6 +3,7 @@ package utils import ( "encoding/json" "fmt" + "log" "slices" "strings" "time" @@ -35,17 +36,16 @@ import ( ) // NOTE: required to ensure consitent precision of bg values in the platform -func getBGValuePrecision(val interface{}) *float64 { +func getBGValuePrecision(val float64) *float64 { + //log.Printf("In VAL %v", val) floatStr := fmt.Sprintf("%v", val) - floatParts := strings.Split(floatStr, ".") - if len(floatParts) == 2 { - if len(floatParts[1]) > 5 { - if floatVal, ok := val.(float64); ok { - mgdlVal := floatVal * glucose.MmolLToMgdLConversionFactor - intValue := int(mgdlVal/glucose.MmolLToMgdLConversionFactor*glucose.MmolLToMgdLPrecisionFactor + 0.5) - floatValue := float64(intValue) / glucose.MmolLToMgdLPrecisionFactor - return &floatValue - } + if _, floatParts, found := strings.Cut(floatStr, "."); found { + if len(floatParts) > 5 { + mgdlVal := val * glucose.MmolLToMgdLConversionFactor + intValue := int(mgdlVal/glucose.MmolLToMgdLConversionFactor*glucose.MmolLToMgdLPrecisionFactor + 0.5) + floatValue := float64(intValue) / glucose.MmolLToMgdLPrecisionFactor + //log.Printf("Out VAL %v", floatValue) + return &floatValue } } return nil @@ -66,194 +66,212 @@ func getTarget(bgTarget interface{}) (*glucose.Target, error) { func setGlucoseTargetPrecision(target *glucose.Target) *glucose.Target { if bg := target.High; bg != nil { - if val := getBGValuePrecision(bg); val != nil { + if val := getBGValuePrecision(*bg); val != nil { target.High = val } } if bg := target.Low; bg != nil { - if val := getBGValuePrecision(bg); val != nil { + if val := getBGValuePrecision(*bg); val != nil { target.Low = val } } if bg := target.Range; bg != nil { - if val := getBGValuePrecision(bg); val != nil { + if val := getBGValuePrecision(*bg); val != nil { target.Range = val } } if low := target.Target; low != nil { - if val := getBGValuePrecision(low); val != nil { + if val := getBGValuePrecision(*low); val != nil { target.Target = val } } return target } -func ApplyBaseChanges(bsonData bson.M, dataType string) error { +func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[string]interface{}, error) { + + updatedObject := incomingObject - switch dataType { + switch b.datumType { case pump.Type: - if boluses := bsonData["bolus"]; boluses != nil { + if boluses := updatedObject["bolus"]; boluses != nil { // NOTE: fix mis-named boluses which were saved in jellyfish as a `bolus` - bsonData["boluses"] = boluses - delete(bsonData, "bolus") + updatedObject["boluses"] = boluses + delete(updatedObject, "bolus") } - if schedules := bsonData["sleepSchedules"]; schedules != nil { + if schedules := updatedObject["sleepSchedules"]; schedules != nil { // NOTE: this is to fix sleepSchedules so they are in the required map format scheduleNames := map[int]string{0: "1", 1: "2"} sleepScheduleMap := pump.SleepScheduleMap{} dataBytes, err := json.Marshal(schedules) if err != nil { - return err + return nil, err } schedulesArray := []*pump.SleepSchedule{} err = json.Unmarshal(dataBytes, &schedulesArray) if err != nil { - return err + return nil, err } for i, schedule := range schedulesArray { days := schedule.Days updatedDays := []string{} for _, day := range *days { if !slices.Contains(common.DaysOfWeek(), strings.ToLower(day)) { - return errorsP.Newf("pumpSettings.sleepSchedules has an invalid day of week %s", day) + return nil, errorsP.Newf("pumpSettings.sleepSchedules has an invalid day of week %s", day) } updatedDays = append(updatedDays, strings.ToLower(day)) } schedule.Days = &updatedDays sleepScheduleMap[scheduleNames[i]] = schedule } - bsonData["sleepSchedules"] = &sleepScheduleMap + updatedObject["sleepSchedules"] = &sleepScheduleMap } - if bgTargetPhysicalActivity := bsonData["bgTargetPhysicalActivity"]; bgTargetPhysicalActivity != nil { - target, err := getTarget(bgTargetPhysicalActivity) - if err != nil { - return err - } - bsonData["bgTargetPhysicalActivity"] = setGlucoseTargetPrecision(target) + if bgTargetPhysicalActivity := updatedObject["bgTargetPhysicalActivity"]; bgTargetPhysicalActivity != nil { + // target, err := getTarget(bgTargetPhysicalActivity) + // if err != nil { + // return nil, err + // } + // updatedObject["bgTargetPhysicalActivity"] = *setGlucoseTargetPrecision(target) } - if bgTargetPreprandial := bsonData["bgTargetPreprandial"]; bgTargetPreprandial != nil { + if bgTargetPreprandial := updatedObject["bgTargetPreprandial"]; bgTargetPreprandial != nil { target, err := getTarget(bgTargetPreprandial) if err != nil { - return err + return nil, err } - bsonData["bgTargetPreprandial"] = setGlucoseTargetPrecision(target) + updatedObject["bgTargetPreprandial"] = *setGlucoseTargetPrecision(target) } - if bgTarget := bsonData["bgTarget"]; bgTarget != nil { - - var bgTargetStartArry pump.BloodGlucoseTargetStartArray - + if bgTarget := updatedObject["bgTarget"]; bgTarget != nil { + //var bgTargetStartArry pump.BloodGlucoseTargetStartArray dataBytes, err := json.Marshal(bgTarget) if err != nil { - return err - } - err = json.Unmarshal(dataBytes, &bgTargetStartArry) - if err != nil { - return errorsP.Newf("bgTarget %s", string(dataBytes)) + return nil, err } + log.Printf("## bgTarget %s", string(dataBytes)) + // err = json.Unmarshal(dataBytes, &bgTargetStartArry) + // if err != nil { + // return nil, errorsP.Newf("bgTarget %s", string(dataBytes)) + // } - for _, item := range bgTargetStartArry { - item.Target = *setGlucoseTargetPrecision(&item.Target) - } + // for i, item := range bgTargetStartArry { + // log.Printf("## bgTargetStartArray %d %v", i, item.Target) + + // target := setGlucoseTargetPrecision(&item.Target) + + // log.Printf("## updated target %v", *target.Target) + + // bgTargetStartArry[i].Target = *target - bsonData["bgTarget"] = &bgTargetStartArry + // log.Printf("## updated target %v", *bgTargetStartArry[i].Target.Target) + // } + + // updatedObject["bgTarget"] = bgTargetStartArry } - if bgTargets := bsonData["bgTargets"]; bgTargets != nil { - var data pump.BloodGlucoseTargetStartArrayMap + if bgTargets := updatedObject["bgTargets"]; bgTargets != nil { + //var data pump.BloodGlucoseTargetStartArrayMap dataBytes, err := json.Marshal(bgTargets) if err != nil { - return err - } - err = json.Unmarshal(dataBytes, &data) - if err != nil { - return err + return nil, err } - for i, d := range data { - for x, t := range *d { - t.Target = *setGlucoseTargetPrecision(&t.Target) - (*d)[x] = t - } - data[i] = d - } - bsonData["bgTargets"] = data + log.Printf("## bgTargets %s", string(dataBytes)) + // err = json.Unmarshal(dataBytes, &data) + // if err != nil { + // return nil, err + // } + + // for i, d := range data { + // for x, t := range *d { + // t.Target = *setGlucoseTargetPrecision(&t.Target) + // (*d)[x] = t + // } + // data[i] = d + // } + // log.Print("## setting updated targets") + // updatedObject["bgTargets"] = data } - if overridePresets := bsonData["overridePresets"]; overridePresets != nil { - var overridePresetMap pump.OverridePresetMap - dataBytes, err := json.Marshal(overridePresets) - if err != nil { - return err - } - err = json.Unmarshal(dataBytes, &overridePresetMap) - if err != nil { - return err - } - for i, p := range overridePresetMap { - overridePresetMap[i].BloodGlucoseTarget = setGlucoseTargetPrecision(p.BloodGlucoseTarget) - } - bsonData["overridePresets"] = &overridePresetMap + if overridePresets := updatedObject["overridePresets"]; overridePresets != nil { + // var overridePresetMap pump.OverridePresetMap + // dataBytes, err := json.Marshal(overridePresets) + // if err != nil { + // return nil, err + // } + // err = json.Unmarshal(dataBytes, &overridePresetMap) + // if err != nil { + // return nil, err + // } + // for i, p := range overridePresetMap { + // overridePresetMap[i].BloodGlucoseTarget = setGlucoseTargetPrecision(p.BloodGlucoseTarget) + // } + // updatedObject["overridePresets"] = &overridePresetMap } case selfmonitored.Type, ketone.Type, continuous.Type: - units := fmt.Sprintf("%v", bsonData["units"]) + units := fmt.Sprintf("%v", updatedObject["units"]) if units == glucose.MmolL || units == glucose.Mmoll { - if val := getBGValuePrecision(bsonData["value"]); val != nil { - bsonData["value"] = *val + if bgVal, ok := updatedObject["value"].(float64); ok { + if val := getBGValuePrecision(bgVal); val != nil { + updatedObject["value"] = *val + } } } case cgm.Type: - units := fmt.Sprintf("%v", bsonData["units"]) + units := fmt.Sprintf("%v", updatedObject["units"]) if units == glucose.MmolL || units == glucose.Mmoll { - if lowAlerts, ok := bsonData["lowAlerts"].(bson.M); ok { - if val := getBGValuePrecision(lowAlerts["level"]); val != nil { - lowAlerts["level"] = *val - bsonData["lowAlerts"] = lowAlerts + if lowAlerts, ok := updatedObject["lowAlerts"].(bson.M); ok { + if bgVal, ok := lowAlerts["level"].(float64); ok { + if val := getBGValuePrecision(bgVal); val != nil { + lowAlerts["level"] = *val + updatedObject["lowAlerts"] = lowAlerts + } } } - if highAlerts, ok := bsonData["highAlerts"].(bson.M); ok { - if val := getBGValuePrecision(highAlerts["level"]); val != nil { - highAlerts["level"] = *val - bsonData["highAlerts"] = highAlerts + if highAlerts, ok := updatedObject["highAlerts"].(bson.M); ok { + if bgVal, ok := highAlerts["level"].(float64); ok { + if val := getBGValuePrecision(bgVal); val != nil { + highAlerts["level"] = *val + updatedObject["highAlerts"] = highAlerts + } } } } case calculator.Type: - if bolus := bsonData["bolus"]; bolus != nil { + if bolus := updatedObject["bolus"]; bolus != nil { // NOTE: we are doing this to ensure that the `bolus` is just a string reference if _, ok := bolus.(string); ok { - delete(bsonData, "bolus") + delete(updatedObject, "bolus") } } - if bgTarget := bsonData["bgTarget"]; bgTarget != nil { + if bgTarget := updatedObject["bgTarget"]; bgTarget != nil { target, err := getTarget(bgTarget) if err != nil { - return err + return nil, err } - bsonData["bgTarget"] = setGlucoseTargetPrecision(target) + updatedObject["bgTarget"] = setGlucoseTargetPrecision(target) } - if bgInput := bsonData["bgInput"]; bgInput != nil { + if bgInput, ok := updatedObject["bgInput"].(float64); ok { if val := getBGValuePrecision(bgInput); val != nil { - bsonData["bgInput"] = val + updatedObject["bgInput"] = *val } } case device.Type: - subType := fmt.Sprintf("%v", bsonData["subType"]) + subType := fmt.Sprintf("%v", updatedObject["subType"]) switch subType { case reservoirchange.SubType, alarm.SubType: // NOTE: we are doing this to ensure that the `status` is just a string reference and then setting the `statusId` with it - if status := bsonData["status"]; status != nil { + if status := updatedObject["status"]; status != nil { if statusID, ok := status.(string); ok { - bsonData["statusId"] = statusID - delete(bsonData, "status") + updatedObject["statusId"] = statusID + delete(updatedObject, "status") } } } } - if payload := bsonData["payload"]; payload != nil { + if payload := updatedObject["payload"]; payload != nil { if m, ok := payload.(bson.M); ok { if length := len(m); length == 0 { - delete(bsonData, "payload") + delete(updatedObject, "payload") } } @@ -261,26 +279,26 @@ func ApplyBaseChanges(bsonData bson.M, dataType string) error { var payloadMetadata metadata.Metadata err := json.Unmarshal(json.RawMessage(strPayload), &payloadMetadata) if err != nil { - return errorsP.Newf("payload could not be set from %s", strPayload) + return nil, errorsP.Newf("payload could not be set from %s", strPayload) } - bsonData["payload"] = &payloadMetadata + updatedObject["payload"] = &payloadMetadata } } - if annotations := bsonData["annotations"]; annotations != nil { + if annotations := updatedObject["annotations"]; annotations != nil { if strAnnotations, ok := annotations.(string); ok { var metadataArray metadata.MetadataArray if err := json.Unmarshal(json.RawMessage(strAnnotations), &metadataArray); err != nil { - return errorsP.Newf("annotations could not be set from %s", strAnnotations) + return nil, errorsP.Newf("annotations could not be set from %s", strAnnotations) } - bsonData["annotations"] = &metadataArray + updatedObject["annotations"] = &metadataArray } } - return nil + return updatedObject, nil } -func BuildPlatformDatum(objID string, objType string, objectData map[string]interface{}) (*data.Datum, error) { - parser := structureParser.NewObject(&objectData) +func (b *builder) buildDatum(obj map[string]interface{}) error { + parser := structureParser.NewObject(&obj) validator := structureValidator.New() normalizer := dataNormalizer.New() @@ -291,7 +309,7 @@ func BuildPlatformDatum(objID string, objType string, objectData map[string]inte (*datum).Validate(validator) (*datum).Normalize(normalizer) } else { - return nil, errorsP.Newf("no datum returned for id=[%s]", objID) + return errorsP.Newf("no datum returned for id=[%s]", b.datumID) } validator.Bool("_active", parser.Bool("_active")).Exists() @@ -310,7 +328,7 @@ func BuildPlatformDatum(objID string, objType string, objectData map[string]inte //parsed but not used in the platform //deletes will be created from the diff - switch objType { + switch b.datumType { case continuous.Type: validator.String("subType", parser.String("subType")) case bolus.Type: @@ -334,25 +352,25 @@ func BuildPlatformDatum(objID string, objType string, objectData map[string]inte parser.NotParsed() if err := parser.Error(); err != nil { - return nil, err + return err } if err := validator.Error(); err != nil { - return nil, err + return err } if err := normalizer.Error(); err != nil { - return nil, err + return err } fields, err := (*datum).IdentityFields() if err != nil { - return nil, errorsP.Wrap(err, "unable to gather identity fields for datum") + return errorsP.Wrap(err, "unable to gather identity fields for datum") } hash, err := deduplicator.GenerateIdentityHash(fields) if err != nil { - return nil, errorsP.Wrap(err, "unable to generate identity hash for datum") + return errorsP.Wrap(err, "unable to generate identity hash for datum") } deduplicator := (*datum).DeduplicatorDescriptor() @@ -363,23 +381,26 @@ func BuildPlatformDatum(objID string, objType string, objectData map[string]inte (*datum).SetDeduplicatorDescriptor(deduplicator) - return datum, nil + b.datum = *datum + return nil } -func GetDatumChanges(id string, datum interface{}, original map[string]interface{}) ([]bson.M, []bson.M, error) { +func (b *builder) datumChanges(storedObj map[string]interface{}) ([]bson.M, []bson.M, error) { - outgoingJSONData, err := json.Marshal(datum) + datumJSON, err := json.Marshal(b.datum) if err != nil { return nil, nil, err } - processedObject := map[string]interface{}{} - if err := json.Unmarshal(outgoingJSONData, &processedObject); err != nil { + // log.Printf("datum: %s", string(datumJSON)) + + datumObject := map[string]interface{}{} + if err := json.Unmarshal(datumJSON, &datumObject); err != nil { return nil, nil, err } - if deduplicator := processedObject["deduplicator"]; deduplicator != nil { - processedObject["_deduplicator"] = deduplicator + if deduplicator := datumObject["deduplicator"]; deduplicator != nil { + datumObject["_deduplicator"] = deduplicator } // these are extras that we want to leave on the @@ -397,14 +418,15 @@ func GetDatumChanges(id string, datum interface{}, original map[string]interface "modifiedTime", "uploadId", "deduplicator", + "time", } for _, key := range notRequired { - delete(original, key) - delete(processedObject, key) + delete(storedObj, key) + delete(datumObject, key) } - changelog, err := diff.Diff(original, processedObject, diff.StructMapKeySupport()) + changelog, err := diff.Diff(storedObj, datumObject, diff.StructMapKeySupport()) if err != nil { return nil, nil, err } @@ -445,29 +467,43 @@ func GetDatumChanges(id string, datum interface{}, original map[string]interface return apply, revert, nil } -func ProcessDatum(dataID string, dataType string, bsonData bson.M) ([]bson.M, error) { +type builder struct { + datumType string + datumID string + datum data.Datum +} - if err := ApplyBaseChanges(bsonData, dataType); err != nil { - return nil, err +func ProcessDatum(dataID string, dataType string, bsonData bson.M) ([]bson.M, []bson.M, error) { + + b := &builder{ + datumType: dataType, + datumID: dataID, } - incomingJSONData, err := json.Marshal(bsonData) + storedJSON, err := json.Marshal(bsonData) if err != nil { - return nil, err + return nil, nil, err } - ojbData := map[string]interface{}{} - if err := json.Unmarshal(incomingJSONData, &ojbData); err != nil { - return nil, err + + // log.Printf("# FROM BSON %s", string(storedJSON)) + + storedData := map[string]interface{}{} + if err := json.Unmarshal(storedJSON, &storedData); err != nil { + return nil, nil, err } - datum, err := BuildPlatformDatum(dataID, dataType, ojbData) + updatedData, err := b.applyBaseUpdates(storedData) if err != nil { - return nil, err + return nil, nil, err } - apply, _, err := GetDatumChanges(dataID, datum, ojbData) + if err := b.buildDatum(updatedData); err != nil { + return nil, nil, err + } + + apply, revert, err := b.datumChanges(storedData) if err != nil { - return nil, err + return nil, nil, err } - return apply, nil + return apply, revert, nil } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index bbd0004f50..adcd4d93c1 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -1,31 +1,12 @@ package utils_test import ( - "encoding/json" "fmt" - "log" - "strings" - "time" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/bson/primitive" - - "github.com/tidepool-org/platform/data/blood/glucose" - "github.com/tidepool-org/platform/data/types/basal" - "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" - glucoseTest "github.com/tidepool-org/platform/data/types/blood/glucose/test" - "github.com/tidepool-org/platform/data/types/calculator" - "github.com/tidepool-org/platform/data/types/common" - "github.com/tidepool-org/platform/data/types/device" - "github.com/tidepool-org/platform/data/types/device/reservoirchange" - dataTypesDeviceTest "github.com/tidepool-org/platform/data/types/device/test" - "github.com/tidepool-org/platform/data/types/settings/cgm" - "github.com/tidepool-org/platform/data/types/settings/pump" - pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" - "github.com/tidepool-org/platform/metadata" - metadataTest "github.com/tidepool-org/platform/metadata/test" + "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils/test" ) @@ -39,449 +20,545 @@ var _ = Describe("back-37", func() { return bsonData } - var datumSetup = func(testObj map[string]interface{}) (map[string]interface{}, error) { - bsonData := getBSONData(testObj) - objType := fmt.Sprintf("%v", bsonData["type"]) - utils.ApplyBaseChanges(bsonData, objType) - incomingJSONData, err := json.Marshal(bsonData) - if err != nil { - return nil, err - } - cleanedObject := map[string]interface{}{} - if err := json.Unmarshal(incomingJSONData, &cleanedObject); err != nil { - return nil, err - } - return cleanedObject, nil - } + // var datumSetup = func(testObj map[string]interface{}) (map[string]interface{}, error) { + // bsonData := getBSONData(testObj) + // objType := fmt.Sprintf("%v", bsonData["type"]) + // utils.ApplyBaseChanges(bsonData, objType) + // incomingJSONData, err := json.Marshal(bsonData) + // if err != nil { + // return nil, err + // } + // cleanedObject := map[string]interface{}{} + // if err := json.Unmarshal(incomingJSONData, &cleanedObject); err != nil { + // return nil, err + // } + // return cleanedObject, nil + // } - var _ = Describe("BuildPlatformDatum", func() { - It("should successfully build basal datum", func() { - basalData, err := datumSetup(test.AutomatedBasalTandem) - Expect(err).To(BeNil()) - datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", basalData["_id"]), basal.Type, basalData) - Expect(err).To(BeNil()) - Expect(datum).ToNot(BeNil()) - Expect((*datum).GetType()).To(Equal(basal.Type)) - }) - It("should successfully build dexcom g5 datum", func() { - cbgData, err := datumSetup(test.CBGDexcomG5MobDatum) - Expect(err).To(BeNil()) - datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", cbgData["_id"]), continuous.Type, cbgData) - Expect(err).To(BeNil()) - Expect(datum).ToNot(BeNil()) - Expect((*datum).GetType()).To(Equal(continuous.Type)) - }) - It("should successfully build carelink pump settings", func() { - pSettingsData, err := datumSetup(test.PumpSettingsCarelink) - Expect(err).To(BeNil()) - datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", pSettingsData["_id"]), pump.Type, pSettingsData) - Expect(err).To(BeNil()) - Expect(datum).ToNot(BeNil()) - Expect((*datum).GetType()).To(Equal(pump.Type)) - }) - It("should successfully build omnipod pump settings", func() { - pSettingsData, err := datumSetup(test.PumpSettingsOmnipod) - Expect(err).To(BeNil()) - datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", pSettingsData["_id"]), pump.Type, pSettingsData) - Expect(err).To(BeNil()) - Expect(datum).ToNot(BeNil()) - Expect((*datum).GetType()).To(Equal(pump.Type)) - }) - It("should successfully build tandem pump settings", func() { - pSettingsData, err := datumSetup(test.PumpSettingsTandem) - Expect(err).To(BeNil()) - datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", pSettingsData["_id"]), pump.Type, pSettingsData) - Expect(err).To(BeNil()) - Expect(datum).ToNot(BeNil()) - Expect((*datum).GetType()).To(Equal(pump.Type)) - }) - It("should successfully build tandem wizard", func() { - calcData, err := datumSetup(test.WizardTandem) - Expect(err).To(BeNil()) - datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", calcData["_id"]), calculator.Type, calcData) - Expect(err).To(BeNil()) - Expect(datum).ToNot(BeNil()) - Expect((*datum).GetType()).To(Equal(calculator.Type)) - }) - It("should successfully build device event", func() { - deviceEventData, err := datumSetup(test.ReservoirChange) - Expect(err).To(BeNil()) - datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", deviceEventData["_id"]), device.Type, deviceEventData) - Expect(err).To(BeNil()) - Expect(datum).ToNot(BeNil()) - Expect((*datum).GetType()).To(Equal(device.Type)) - }) - It("should successfully build cgm settings", func() { - deviceEventData, err := datumSetup(test.CGMSetting) - Expect(err).To(BeNil()) - datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", deviceEventData["_id"]), cgm.Type, deviceEventData) - Expect(err).To(BeNil()) - Expect(datum).ToNot(BeNil()) - Expect((*datum).GetType()).To(Equal(cgm.Type)) - }) - }) + // var _ = Describe("BuildPlatformDatum", func() { - var _ = Describe("ApplyBaseChanges", func() { + // It("should successfully build basal datum", func() { + // Skip("todo") + // basalData, err := datumSetup(test.AutomatedBasalTandem) + // Expect(err).To(BeNil()) + // datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", basalData["_id"]), basal.Type, basalData) + // Expect(err).To(BeNil()) + // Expect(datum).ToNot(BeNil()) + // Expect((*datum).GetType()).To(Equal(basal.Type)) + // }) + // It("should successfully build dexcom g5 datum", func() { + // Skip("todo") + // cbgData, err := datumSetup(test.CBGDexcomG5MobDatum) + // Expect(err).To(BeNil()) + // datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", cbgData["_id"]), continuous.Type, cbgData) + // Expect(err).To(BeNil()) + // Expect(datum).ToNot(BeNil()) + // Expect((*datum).GetType()).To(Equal(continuous.Type)) + // }) + // It("should successfully build carelink pump settings", func() { + // Skip("todo") + // pSettingsData, err := datumSetup(test.PumpSettingsCarelink) + // Expect(err).To(BeNil()) + // datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", pSettingsData["_id"]), pump.Type, pSettingsData) + // Expect(err).To(BeNil()) + // Expect(datum).ToNot(BeNil()) + // Expect((*datum).GetType()).To(Equal(pump.Type)) + // }) + // It("should successfully build omnipod pump settings", func() { + // Skip("todo") + // pSettingsData, err := datumSetup(test.PumpSettingsOmnipod) + // Expect(err).To(BeNil()) + // datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", pSettingsData["_id"]), pump.Type, pSettingsData) + // Expect(err).To(BeNil()) + // Expect(datum).ToNot(BeNil()) + // Expect((*datum).GetType()).To(Equal(pump.Type)) + // }) + // It("should successfully build tandem pump settings", func() { + // Skip("todo") + // pSettingsData, err := datumSetup(test.PumpSettingsTandem) + // Expect(err).To(BeNil()) + // datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", pSettingsData["_id"]), pump.Type, pSettingsData) + // Expect(err).To(BeNil()) + // Expect(datum).ToNot(BeNil()) + // Expect((*datum).GetType()).To(Equal(pump.Type)) + // }) + // It("should successfully build tandem wizard", func() { + // Skip("todo") + // calcData, err := datumSetup(test.WizardTandem) + // Expect(err).To(BeNil()) + // datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", calcData["_id"]), calculator.Type, calcData) + // Expect(err).To(BeNil()) + // Expect(datum).ToNot(BeNil()) + // Expect((*datum).GetType()).To(Equal(calculator.Type)) + // }) + // It("should successfully build device event", func() { + // Skip("todo") + // deviceEventData, err := datumSetup(test.ReservoirChange) + // Expect(err).To(BeNil()) + // datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", deviceEventData["_id"]), device.Type, deviceEventData) + // Expect(err).To(BeNil()) + // Expect(datum).ToNot(BeNil()) + // Expect((*datum).GetType()).To(Equal(device.Type)) + // }) + // It("should successfully build cgm settings", func() { + // Skip("todo") + // deviceEventData, err := datumSetup(test.CGMSetting) + // Expect(err).To(BeNil()) + // datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", deviceEventData["_id"]), cgm.Type, deviceEventData) + // Expect(err).To(BeNil()) + // Expect(datum).ToNot(BeNil()) + // Expect((*datum).GetType()).To(Equal(cgm.Type)) + // }) + // }) - const expectedID = "some-id" - var pumpSettingsDatum *pump.Pump + // var _ = Describe("ApplyBaseChanges", func() { + // const expectedID = "some-id" + // var pumpSettingsDatum *pump.Pump - BeforeEach(func() { - mmolL := pump.DisplayBloodGlucoseUnitsMmolPerL - pumpSettingsDatum = pumpTest.NewPump(&mmolL) - *pumpSettingsDatum.ID = expectedID - *pumpSettingsDatum.UserID = "some-user-id" - *pumpSettingsDatum.DeviceID = "some-device-id" - theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") - *pumpSettingsDatum.Time = theTime - }) - Context("pumpSettings datum with mis-named jellyfish bolus", func() { - var bolusData = &pump.BolusMap{ - "bolus-1": pumpTest.NewRandomBolus(), - "bolus-2": pumpTest.NewRandomBolus(), - } - var settingsBolusDatum bson.M - var datumType string - - BeforeEach(func() { - - settingsBolusDatum = getBSONData(pumpSettingsDatum) - settingsBolusDatum["bolus"] = bolusData - settingsBolusDatum["_id"] = expectedID - datumType = fmt.Sprintf("%v", settingsBolusDatum["type"]) - }) - - It("should do nothing when has no bolus", func() { - settingsBolusDatum["bolus"] = nil - Expect(settingsBolusDatum["bolus"]).To(BeNil()) - err := utils.ApplyBaseChanges(settingsBolusDatum, datumType) - Expect(err).To(BeNil()) - Expect(settingsBolusDatum["bolus"]).To(BeNil()) - Expect(settingsBolusDatum["boluses"]).To(BeNil()) - }) - - It("should rename as boluses when bolus found", func() { - Expect(settingsBolusDatum["bolus"]).ToNot(BeNil()) - err := utils.ApplyBaseChanges(settingsBolusDatum, datumType) - Expect(err).To(BeNil()) - Expect(settingsBolusDatum["bolus"]).To(BeNil()) - Expect(settingsBolusDatum["boluses"]).ToNot(BeNil()) - Expect(settingsBolusDatum["boluses"]).To(Equal(bolusData)) - }) - }) - Context("pumpSettings datum with unordered sleepSchedules", func() { - expectedSleepSchedulesMap := &pump.SleepScheduleMap{} - var invalidDays *pump.SleepSchedule - var s1Days *pump.SleepSchedule - var s2Days *pump.SleepSchedule - var sleepSchedulesDatum bson.M - var datumType string - - BeforeEach(func() { - sleepSchedulesDatum = getBSONData(pumpSettingsDatum) - datumType = fmt.Sprintf("%v", sleepSchedulesDatum["type"]) - s1 := pumpTest.RandomSleepSchedule() - s2 := pumpTest.RandomSleepSchedule() - (*expectedSleepSchedulesMap)["1"] = s1 - (*expectedSleepSchedulesMap)["2"] = s2 - - s1Days = pumpTest.CloneSleepSchedule(s1) - for key, day := range *s1Days.Days { - (*s1Days.Days)[key] = strings.ToUpper(day) - } - s2Days = pumpTest.CloneSleepSchedule(s2) - for key, day := range *s2Days.Days { - (*s2Days.Days)[key] = strings.ToUpper(day) - } - invalidDays = pumpTest.CloneSleepSchedule(s2) - invalidDays.Days = &[]string{"not-a-day", common.DayFriday} - Expect(expectedSleepSchedulesMap).ToNot(BeNil()) - pumpSettingsDatum.SleepSchedules = nil - sleepSchedulesDatum = getBSONData(pumpSettingsDatum) - sleepSchedulesDatum["_id"] = expectedID - sleepSchedulesDatum["bolus"] = nil //remove as not testing here - }) - - It("does nothing when no sleepSchedules", func() { - sleepSchedulesDatum["sleepSchedules"] = nil - err := utils.ApplyBaseChanges(sleepSchedulesDatum, datumType) - Expect(err).To(BeNil()) - Expect(sleepSchedulesDatum["sleepSchedules"]).To(BeNil()) - }) - It("returns updated sleepSchedules when valid", func() { - sleepSchedulesDatum["sleepSchedules"] = []*pump.SleepSchedule{s1Days, s2Days} - err := utils.ApplyBaseChanges(sleepSchedulesDatum, datumType) - Expect(err).To(BeNil()) - Expect(sleepSchedulesDatum["sleepSchedules"]).ToNot(BeNil()) - Expect(sleepSchedulesDatum["sleepSchedules"]).To(Equal(expectedSleepSchedulesMap)) - }) - It("returns error when sleepSchedules have invalid days", func() { - sleepSchedulesDatum["sleepSchedules"] = []*pump.SleepSchedule{invalidDays} - err := utils.ApplyBaseChanges(sleepSchedulesDatum, datumType) - Expect(err).ToNot(BeNil()) - Expect(err.Error()).To(Equal("pumpSettings.sleepSchedules has an invalid day of week not-a-day")) - }) - }) - Context("datum with glucose", func() { - var newContinuous = func(units *string) *continuous.Continuous { - datum := continuous.New() - datum.Glucose = *glucoseTest.NewGlucose(units) - datum.Type = "cbg" - *datum.ID = expectedID - *datum.UserID = "some-user-id" - *datum.DeviceID = "some-device-id" - theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") - *datum.Time = theTime - return datum - } - datumType := "cbg" - It("should do nothing when value is already correct", func() { - mmoll := glucose.MmolL - cbg := newContinuous(&mmoll) - cbgData := getBSONData(cbg) - cbgData["_id"] = expectedID - cbgData["value"] = 4.88466 - - Expect(cbgData["value"]).To(Equal(4.88466)) - err := utils.ApplyBaseChanges(cbgData, datumType) - Expect(err).To(BeNil()) - Expect(cbgData["value"]).To(Equal(4.88466)) - }) - It("should update the value when the precesion is too accurate correct", func() { - mmoll := glucose.MmolL - cbg := newContinuous(&mmoll) - cbgData := getBSONData(cbg) - cbgData["_id"] = expectedID - cbgData["value"] = 4.88465823212007 - - Expect(cbgData["value"]).To(Equal(4.88465823212007)) - err := utils.ApplyBaseChanges(cbgData, datumType) - Expect(err).To(BeNil()) - Expect(cbgData["value"]).To(Equal(4.88466)) - }) - }) - Context("reservoirChange deviceEvent datum with status string", func() { - var newReservoirChange = func() *reservoirchange.ReservoirChange { - datum := reservoirchange.New() - datum.Device = *dataTypesDeviceTest.RandomDevice() - datum.SubType = "reservoirChange" - return datum - } - It("should convert to statusId", func() { - deviceEvent := newReservoirChange() - deviceEventData := getBSONData(deviceEvent) - deviceEventData["status"] = "some-status-id" - err := utils.ApplyBaseChanges(deviceEventData, deviceEvent.Type) - Expect(err).To(BeNil()) - Expect(deviceEventData["status"]).To(BeNil()) - Expect(deviceEventData["statusId"]).To(Equal("some-status-id")) - }) - }) - Context("wizard datum with bolus string", func() { - It("should convert to bolusId for datum validation", func() { - wizardBSON := getBSONData(test.WizardTandem) - Expect(wizardBSON["bolus"]).ToNot(BeNil()) - err := utils.ApplyBaseChanges(wizardBSON, calculator.Type) - Expect(err).To(BeNil()) - Expect(wizardBSON["bolus"]).To(BeNil()) - }) - }) - Context("datum with string payload", func() { - var datumWithPayload primitive.M - var datumType string - var payload *metadata.Metadata - BeforeEach(func() { - datumWithPayload = getBSONData(pumpSettingsDatum) - payload = metadataTest.RandomMetadata() - datumWithPayload["payload"] = *payload - datumType = fmt.Sprintf("%v", datumWithPayload["type"]) - }) - - It("should do nothing when value is already correct", func() { - Expect(datumWithPayload["payload"]).To(Equal(*payload)) - err := utils.ApplyBaseChanges(datumWithPayload, datumType) - Expect(err).To(BeNil()) - Expect(datumWithPayload["payload"]).To(Equal(*payload)) - }) - It("should update the payload when it is a string", func() { - datumWithPayload["payload"] = `{"transmitterId":"410X6M","transmitterTicks":5796922,"trend":"flat"}` - err := utils.ApplyBaseChanges(datumWithPayload, datumType) - Expect(err).To(BeNil()) - Expect(datumWithPayload["payload"]).To(Equal(&metadata.Metadata{ - "transmitterId": "410X6M", - "transmitterTicks": float64(5796922), - "trend": "flat", - })) - }) - It("should remove the payload when it is empty", func() { - datumWithPayload["payload"] = bson.M{} - err := utils.ApplyBaseChanges(datumWithPayload, datumType) - Expect(err).To(BeNil()) - Expect(datumWithPayload["payload"]).To(BeNil()) - }) - }) - Context("datum with string annotations", func() { - var datumWithAnnotation primitive.M - var annotations *metadata.MetadataArray - var datumType string - BeforeEach(func() { - datumWithAnnotation = getBSONData(pumpSettingsDatum) - annotations = metadataTest.RandomMetadataArray() - datumWithAnnotation["annotations"] = *annotations - datumType = fmt.Sprintf("%v", datumWithAnnotation["type"]) - }) - - It("should do nothing when value is already correct", func() { - Expect(datumWithAnnotation["annotations"]).To(Equal(*annotations)) - err := utils.ApplyBaseChanges(datumWithAnnotation, datumType) - Expect(err).To(BeNil()) - Expect(datumWithAnnotation["annotations"]).To(Equal(*annotations)) - }) - It("should update the annotations when it is a string", func() { - datumWithAnnotation["annotations"] = `[{"code":"bg/out-of-range","threshold":40,"value":"low"}]` - err := utils.ApplyBaseChanges(datumWithAnnotation, datumType) - Expect(err).To(BeNil()) - Expect(datumWithAnnotation["annotations"]).To(Equal(&metadata.MetadataArray{ - &metadata.Metadata{ - "code": "bg/out-of-range", - "threshold": float64(40), - "value": "low", - }, - })) - }) - }) - }) + // BeforeEach(func() { + // mmolL := pump.DisplayBloodGlucoseUnitsMmolPerL + // pumpSettingsDatum = pumpTest.NewPump(&mmolL) + // *pumpSettingsDatum.ID = expectedID + // *pumpSettingsDatum.UserID = "some-user-id" + // *pumpSettingsDatum.DeviceID = "some-device-id" + // theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") + // *pumpSettingsDatum.Time = theTime + // }) + // Context("pumpSettings datum with mis-named jellyfish bolus", func() { + // var bolusData = &pump.BolusMap{ + // "bolus-1": pumpTest.NewRandomBolus(), + // "bolus-2": pumpTest.NewRandomBolus(), + // } + // var settingsBolusDatum bson.M + // var datumType string + + // BeforeEach(func() { + // settingsBolusDatum = getBSONData(pumpSettingsDatum) + // settingsBolusDatum["bolus"] = bolusData + // settingsBolusDatum["_id"] = expectedID + // datumType = fmt.Sprintf("%v", settingsBolusDatum["type"]) + // }) + + // It("should do nothing when has no bolus", func() { + // Skip("todo") + // settingsBolusDatum["bolus"] = nil + // Expect(settingsBolusDatum["bolus"]).To(BeNil()) + // err := utils.ApplyBaseChanges(settingsBolusDatum, datumType) + // Expect(err).To(BeNil()) + // Expect(settingsBolusDatum["bolus"]).To(BeNil()) + // Expect(settingsBolusDatum["boluses"]).To(BeNil()) + // }) + + // It("should rename as boluses when bolus found", func() { + // Skip("todo") + // Expect(settingsBolusDatum["bolus"]).ToNot(BeNil()) + // err := utils.ApplyBaseChanges(settingsBolusDatum, datumType) + // Expect(err).To(BeNil()) + // Expect(settingsBolusDatum["bolus"]).To(BeNil()) + // Expect(settingsBolusDatum["boluses"]).ToNot(BeNil()) + // Expect(settingsBolusDatum["boluses"]).To(Equal(bolusData)) + // }) + // }) + // Context("pumpSettings datum with unordered sleepSchedules", func() { + // expectedSleepSchedulesMap := &pump.SleepScheduleMap{} + // var invalidDays *pump.SleepSchedule + // var s1Days *pump.SleepSchedule + // var s2Days *pump.SleepSchedule + // var sleepSchedulesDatum bson.M + // var datumType string + + // BeforeEach(func() { + // sleepSchedulesDatum = getBSONData(pumpSettingsDatum) + // datumType = fmt.Sprintf("%v", sleepSchedulesDatum["type"]) + // s1 := pumpTest.RandomSleepSchedule() + // s2 := pumpTest.RandomSleepSchedule() + // (*expectedSleepSchedulesMap)["1"] = s1 + // (*expectedSleepSchedulesMap)["2"] = s2 - var _ = Describe("GetDatumChanges", func() { + // s1Days = pumpTest.CloneSleepSchedule(s1) + // for key, day := range *s1Days.Days { + // (*s1Days.Days)[key] = strings.ToUpper(day) + // } + // s2Days = pumpTest.CloneSleepSchedule(s2) + // for key, day := range *s2Days.Days { + // (*s2Days.Days)[key] = strings.ToUpper(day) + // } + // invalidDays = pumpTest.CloneSleepSchedule(s2) + // invalidDays.Days = &[]string{"not-a-day", common.DayFriday} + // Expect(expectedSleepSchedulesMap).ToNot(BeNil()) + // pumpSettingsDatum.SleepSchedules = nil + // sleepSchedulesDatum = getBSONData(pumpSettingsDatum) + // sleepSchedulesDatum["_id"] = expectedID + // sleepSchedulesDatum["bolus"] = nil //remove as not testing here + // }) - const expectedID = "difference-id" + // It("does nothing when no sleepSchedules", func() { + // Skip("todo") + // sleepSchedulesDatum["sleepSchedules"] = nil + // err := utils.ApplyBaseChanges(sleepSchedulesDatum, datumType) + // Expect(err).To(BeNil()) + // Expect(sleepSchedulesDatum["sleepSchedules"]).To(BeNil()) + // }) + // It("returns updated sleepSchedules when valid", func() { + // Skip("todo") + // sleepSchedulesDatum["sleepSchedules"] = []*pump.SleepSchedule{s1Days, s2Days} + // err := utils.ApplyBaseChanges(sleepSchedulesDatum, datumType) + // Expect(err).To(BeNil()) + // Expect(sleepSchedulesDatum["sleepSchedules"]).ToNot(BeNil()) + // Expect(sleepSchedulesDatum["sleepSchedules"]).To(Equal(expectedSleepSchedulesMap)) + // }) + // It("returns error when sleepSchedules have invalid days", func() { + // Skip("todo") + // sleepSchedulesDatum["sleepSchedules"] = []*pump.SleepSchedule{invalidDays} + // err := utils.ApplyBaseChanges(sleepSchedulesDatum, datumType) + // Expect(err).ToNot(BeNil()) + // Expect(err.Error()).To(Equal("pumpSettings.sleepSchedules has an invalid day of week not-a-day")) + // }) + // }) + // Context("datum with glucose", func() { + // var newContinuous = func(units *string) *continuous.Continuous { + // datum := continuous.New() + // datum.Glucose = *glucoseTest.NewGlucose(units) + // datum.Type = "cbg" + // *datum.ID = expectedID + // *datum.UserID = "some-user-id" + // *datum.DeviceID = "some-device-id" + // theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") + // *datum.Time = theTime + // return datum + // } + // datumType := "cbg" + // It("should do nothing when value is already correct", func() { + // Skip("todo") + // mmoll := glucose.MmolL + // cbg := newContinuous(&mmoll) + // cbgData := getBSONData(cbg) + // cbgData["_id"] = expectedID + // cbgData["value"] = 4.88466 - var getRawData = func(datum interface{}) map[string]interface{} { - var rawObject map[string]interface{} - asByte, _ := json.Marshal(&datum) - json.Unmarshal(asByte, &rawObject) - return rawObject - } + // Expect(cbgData["value"]).To(Equal(4.88466)) + // err := utils.ApplyBaseChanges(cbgData, datumType) + // Expect(err).To(BeNil()) + // Expect(cbgData["value"]).To(Equal(4.88466)) + // }) + // It("should update the value when the precesion is too accurate correct", func() { + // Skip("todo") + // mmoll := glucose.MmolL + // cbg := newContinuous(&mmoll) + // cbgData := getBSONData(cbg) + // cbgData["_id"] = expectedID + // cbgData["value"] = 4.88465823212007 - It("has no difference", func() { - datumObject := getBSONData(test.AutomatedBasalTandem) - incomingObject := getRawData(test.AutomatedBasalTandem) - apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) + // Expect(cbgData["value"]).To(Equal(4.88465823212007)) + // err := utils.ApplyBaseChanges(cbgData, datumType) + // Expect(err).To(BeNil()) + // floatVal := 4.88466 + // Expect(cbgData["value"]).To(Equal(&floatVal)) + // }) + // }) + // Context("reservoirChange deviceEvent datum with status string", func() { + // var newReservoirChange = func() *reservoirchange.ReservoirChange { + // datum := reservoirchange.New() + // datum.Device = *dataTypesDeviceTest.RandomDevice() + // datum.SubType = "reservoirChange" + // return datum + // } + // It("should convert to statusId", func() { + // Skip("todo") + // deviceEvent := newReservoirChange() + // deviceEventData := getBSONData(deviceEvent) + // deviceEventData["status"] = "some-status-id" + // err := utils.ApplyBaseChanges(deviceEventData, deviceEvent.Type) + // Expect(err).To(BeNil()) + // Expect(deviceEventData["status"]).To(BeNil()) + // Expect(deviceEventData["statusId"]).To(Equal("some-status-id")) + // }) + // }) + // Context("wizard datum with bolus string", func() { + // It("should convert to bolusId for datum validation", func() { + // Skip("todo") + // wizardBSON := getBSONData(test.WizardTandem) + // Expect(wizardBSON["bolus"]).ToNot(BeNil()) + // err := utils.ApplyBaseChanges(wizardBSON, calculator.Type) + // Expect(err).To(BeNil()) + // Expect(wizardBSON["bolus"]).To(BeNil()) + // }) + // }) + // Context("datum with string payload", func() { + // var datumWithPayload primitive.M + // var datumType string + // var payload *metadata.Metadata + // BeforeEach(func() { + // datumWithPayload = getBSONData(pumpSettingsDatum) + // payload = metadataTest.RandomMetadata() + // datumWithPayload["payload"] = *payload + // datumType = fmt.Sprintf("%v", datumWithPayload["type"]) + // }) + + // It("should do nothing when value is already correct", func() { + // Skip("todo") + // Expect(datumWithPayload["payload"]).To(Equal(*payload)) + // err := utils.ApplyBaseChanges(datumWithPayload, datumType) + // Expect(err).To(BeNil()) + // Expect(datumWithPayload["payload"]).To(Equal(*payload)) + // }) + // It("should update the payload when it is a string", func() { + // Skip("todo") + // datumWithPayload["payload"] = `{"transmitterId":"410X6M","transmitterTicks":5796922,"trend":"flat"}` + // err := utils.ApplyBaseChanges(datumWithPayload, datumType) + // Expect(err).To(BeNil()) + // Expect(datumWithPayload["payload"]).To(Equal(&metadata.Metadata{ + // "transmitterId": "410X6M", + // "transmitterTicks": float64(5796922), + // "trend": "flat", + // })) + // }) + // It("should remove the payload when it is empty", func() { + // Skip("todo") + // datumWithPayload["payload"] = bson.M{} + // err := utils.ApplyBaseChanges(datumWithPayload, datumType) + // Expect(err).To(BeNil()) + // Expect(datumWithPayload["payload"]).To(BeNil()) + // }) + // }) + // Context("datum with string annotations", func() { + // var datumWithAnnotation primitive.M + // var annotations *metadata.MetadataArray + // var datumType string + // BeforeEach(func() { + // datumWithAnnotation = getBSONData(pumpSettingsDatum) + // annotations = metadataTest.RandomMetadataArray() + // datumWithAnnotation["annotations"] = *annotations + // datumType = fmt.Sprintf("%v", datumWithAnnotation["type"]) + // }) + + // It("should do nothing when value is already correct", func() { + // Skip("todo") + // Expect(datumWithAnnotation["annotations"]).To(Equal(*annotations)) + // err := utils.ApplyBaseChanges(datumWithAnnotation, datumType) + // Expect(err).To(BeNil()) + // Expect(datumWithAnnotation["annotations"]).To(Equal(*annotations)) + // }) + // It("should update the annotations when it is a string", func() { + // Skip("todo") + // datumWithAnnotation["annotations"] = `[{"code":"bg/out-of-range","threshold":40,"value":"low"}]` + // err := utils.ApplyBaseChanges(datumWithAnnotation, datumType) + // Expect(err).To(BeNil()) + // Expect(datumWithAnnotation["annotations"]).To(Equal(&metadata.MetadataArray{ + // &metadata.Metadata{ + // "code": "bg/out-of-range", + // "threshold": float64(40), + // "value": "low", + // }, + // })) + // }) + // }) + // }) + + // var _ = Describe("GetDatumChanges", func() { + + // const expectedID = "difference-id" + + // var getRawData = func(datum interface{}) map[string]interface{} { + // var rawObject map[string]interface{} + // asByte, _ := json.Marshal(&datum) + // json.Unmarshal(asByte, &rawObject) + // return rawObject + // } + + // It("has no difference", func() { + // Skip("Todo") + // datumObject := getBSONData(test.AutomatedBasalTandem) + // incomingObject := getRawData(test.AutomatedBasalTandem) + // apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) + // Expect(err).To(BeNil()) + // Expect(apply).ToNot(BeNil()) + // Expect(apply).To(Equal([]bson.M{})) + // Expect(revert).ToNot(BeNil()) + // Expect(revert).To(Equal([]bson.M{})) + // }) + // It("set for missing properties", func() { + // Skip("Todo") + // datumObject := getBSONData(test.AutomatedBasalTandem) + // incomingObject := getRawData(test.AutomatedBasalTandem) + // delete(incomingObject, "deliveryType") + // apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) + // Expect(err).To(BeNil()) + // Expect(apply).To(Equal([]bson.M{{"$set": bson.M{"deliveryType": "automated"}}})) + // Expect(revert).To(Equal([]bson.M{{"$unset": bson.M{"deliveryType": ""}}})) + // }) + // It("set _deduplicator correctly", func() { + // Skip("Todo") + // calcData, _ := datumSetup(test.WizardTandem) + // id := fmt.Sprintf("%v", calcData["_id"]) + // datum, _ := utils.BuildPlatformDatum(id, calculator.Type, calcData) + // apply, revert, err := utils.GetDatumChanges(id, datum, calcData) + // Expect(err).To(BeNil()) + // Expect(len(apply)).To(Equal(2)) + // Expect(apply[0]["$set"]).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "o6ybZQtDZ95FvuV0zYGphri2SIGesbLCbkHxc1wbbEE="})) + // Expect(len(revert)).To(Equal(2)) + // Expect(revert[0]).Should(HaveKeyWithValue("$unset", bson.M{"_deduplicator": ""})) + // }) + // It("unset for unwanted properties", func() { + // Skip("Todo") + // datumObject := getBSONData(test.AutomatedBasalTandem) + // incomingObject := getRawData(test.AutomatedBasalTandem) + // incomingObject["random"] = map[string]interface{}{"extra": true} + // apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) + // Expect(err).To(BeNil()) + // Expect(len(apply)).To(Equal(1)) + // Expect(apply[0]).Should(HaveKeyWithValue("$unset", bson.M{"random": ""})) + // Expect(len(revert)).To(Equal(1)) + // Expect(revert[0]).Should(HaveKeyWithValue("$set", bson.M{"random": map[string]interface{}{"extra": true}})) + // }) + // It("allow for removing deeply nested properties", func() { + // Skip("Todo") + // datumObject := getBSONData(test.AutomatedBasalTandem) + // incomingObject := getRawData(test.AutomatedBasalTandem) + + // ofThings := map[string]interface{}{ + // "of": map[string]interface{}{ + // "things": map[string]interface{}{ + // "go": map[string]interface{}{ + // "here": true}}}} + // incomingObject["lots"] = ofThings + // apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) + // Expect(err).To(BeNil()) + // Expect(len(apply)).To(Equal(1)) + // Expect(apply[0]).Should(HaveKeyWithValue("$unset", bson.M{"lots": ""})) + // Expect(len(revert)).To(Equal(1)) + // Expect(revert[0]).Should(HaveKeyWithValue("$set", bson.M{"lots": ofThings})) + // }) + // It("allow for updating nested array properties", func() { + // Skip("Todo") + // datumObject := getBSONData(test.PumpSettingsTandem) + // incomingObject := getRawData(test.PumpSettingsTandem) + + // datumObject["insulinSensitivities"] = map[string]interface{}{ + // "Simple": []map[string]interface{}{ + // {"amount": 1.2, "start": 0}, + // {"amount": 2.6, "start": 46800000}, + // }, + // "Standard": []map[string]interface{}{ + // {"amount": 2.7753739955227665, "start": 1000}, + // {"amount": 2.7753739955227665, "start": 46800000}, + // }, + // } + + // apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) + // Expect(err).To(BeNil()) + // Expect(len(apply)).To(Equal(1)) + // Expect(apply[0]).Should(HaveKeyWithValue("$set", bson.M{ + // "insulinSensitivities.Simple.0.amount": 1.2, + // "insulinSensitivities.Simple.1.amount": 2.6, + // "insulinSensitivities.Standard.0.start": float64(1000), + // })) + // Expect(len(revert)).To(Equal(1)) + // Expect(revert[0]).Should(HaveKeyWithValue("$set", bson.M{ + // "insulinSensitivities.Simple.0.amount": 2.7753739955227665, + // "insulinSensitivities.Simple.1.amount": 2.7753739955227665, + // "insulinSensitivities.Standard.0.start": float64(0), + // })) + // }) + // It("no difference when inner payload changes", func() { + // Skip("Todo") + // datumObject := getBSONData(test.AutomatedBasalTandem) + // incomingObject := getRawData(test.AutomatedBasalTandem) + // datumObject["payload"] = map[string]interface{}{"stuff": true} + // apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) + // Expect(err).To(BeNil()) + // Expect(apply).To(Equal([]bson.M{})) + // Expect(revert).To(Equal([]bson.M{})) + // }) + + // It("should convert to bolusId for datum validation", func() { + // Skip("Todo") + // bsonData := getBSONData(test.WizardTandem) + // datumID := fmt.Sprintf("%v", bsonData["_id"]) + // datumType := fmt.Sprintf("%v", bsonData["type"]) + // apply, _, err := utils.ProcessDatum(datumID, datumType, bsonData) + // Expect(err).To(BeNil()) + // Expect(apply[1]["$unset"]).ShouldNot(HaveKey("bolusId")) + // }) + + // It("should update all bgTraget values", func() { + + // bsonObject := getBSONData(test.PumpSettingsCarelink) + // datumID := fmt.Sprintf("%v", bsonObject["_id"]) + // datumType := fmt.Sprintf("%v", bsonObject["type"]) + // apply, revert, err := utils.ProcessDatum(datumID, datumType, bsonObject) + + // Expect(err).To(BeNil()) + // Expect(apply[0]["$set"]).ToNot(BeNil()) + // Expect(len(apply)).To(Equal(2)) + // Expect(apply[0]["$set"]).Should(HaveKeyWithValue("units.bg", "mmol/L")) + // Expect(apply[0]["$set"]).Should(HaveKeyWithValue("bgTarget.0.target", float64(5.55074))) + // Expect(apply[0]["$set"]).Should(HaveKeyWithValue("bgTarget.1.target", float64(5.55074))) + + // Expect(revert[0]["$set"]).ToNot(BeNil()) + // Expect(len(revert)).To(Equal(2)) + // Expect(revert[0]["$set"]).Should(HaveKeyWithValue("units.bg", "mmol/L")) + // Expect(revert[0]["$set"]).Should(HaveKeyWithValue("bgTarget.0.target", float64(5.550747991045533))) + // Expect(revert[0]["$set"]).Should(HaveKeyWithValue("bgTarget.1.target", float64(5.550747991045533))) + // }) + + // It("pump settings omnipod", func() { + // Skip("Todo") + // incomingObject := getRawData(test.PumpSettingsOmnipod) + // datumID := fmt.Sprintf("%v", incomingObject["_id"]) + // datum, _ := utils.BuildPlatformDatum(datumID, pump.Type, incomingObject) + // apply, revert, err := utils.GetDatumChanges(datumID, datum, incomingObject) + // Expect(err).To(BeNil()) + // Expect(len(apply)).To(Equal(2)) + // Expect(apply[0]["$set"]).Should(HaveKeyWithValue("units.bg", "mmol/L")) + // Expect(apply[0]["$set"]).Should(HaveKeyWithValue("bgTarget.0.high", float64(0.40054))) + // Expect(apply[0]["$set"]).Should(HaveKeyWithValue("bgTarget.1.high", float64(0.40054))) + // Expect(apply[0]["$set"]).Should(HaveKeyWithValue("bgTarget.0.target", float64(0.30811))) + // Expect(apply[0]["$set"]).Should(HaveKeyWithValue("bgTarget.1.target", float64(0.30811))) + // Expect(len(revert)).To(Equal(2)) + // Expect(revert[0]["$set"]).Should(HaveKeyWithValue("units.bg", "mmol/L")) + // Expect(revert[0]["$set"]).Should(HaveKeyWithValue("bgTarget.0.high", float64(0.40054))) + // Expect(revert[0]["$set"]).Should(HaveKeyWithValue("bgTarget.1.high", float64(0.40054))) + // Expect(revert[0]["$set"]).Should(HaveKeyWithValue("bgTarget.0.target", float64(0.30811))) + // Expect(revert[0]["$set"]).Should(HaveKeyWithValue("bgTarget.1.target", float64(0.30811))) + // }) + + // }) + + var _ = Describe("ProcessDatum", func() { + + It("basal with unwanted percent feild", func() { + + bsonObject := getBSONData(test.AutomatedBasalTandem) + datumID := fmt.Sprintf("%v", bsonObject["_id"]) + datumType := fmt.Sprintf("%v", bsonObject["type"]) + + apply, revert, err := utils.ProcessDatum(datumID, datumType, bsonObject) Expect(err).To(BeNil()) Expect(apply).ToNot(BeNil()) - Expect(apply).To(Equal([]bson.M{})) Expect(revert).ToNot(BeNil()) - Expect(revert).To(Equal([]bson.M{})) - }) - It("set for missing properties", func() { - datumObject := getBSONData(test.AutomatedBasalTandem) - incomingObject := getRawData(test.AutomatedBasalTandem) - delete(incomingObject, "deliveryType") - apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) - Expect(err).To(BeNil()) - Expect(apply).To(Equal([]bson.M{{"$set": bson.M{"deliveryType": "automated"}}})) - Expect(revert).To(Equal([]bson.M{{"$unset": bson.M{"deliveryType": ""}}})) - }) - It("set _deduplicator correctly", func() { - calcData, _ := datumSetup(test.WizardTandem) - id := fmt.Sprintf("%v", calcData["_id"]) - datum, _ := utils.BuildPlatformDatum(id, calculator.Type, calcData) - apply, revert, err := utils.GetDatumChanges(id, datum, calcData) - Expect(err).To(BeNil()) - Expect(len(apply)).To(Equal(2)) - Expect(apply[0]["$set"]).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "o6ybZQtDZ95FvuV0zYGphri2SIGesbLCbkHxc1wbbEE="})) - Expect(len(revert)).To(Equal(2)) - Expect(revert[0]).Should(HaveKeyWithValue("$unset", bson.M{"_deduplicator": ""})) - }) - It("unset for unwanted properties", func() { - datumObject := getBSONData(test.AutomatedBasalTandem) - incomingObject := getRawData(test.AutomatedBasalTandem) - incomingObject["random"] = map[string]interface{}{"extra": true} - apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) - Expect(err).To(BeNil()) - Expect(len(apply)).To(Equal(1)) - Expect(apply[0]).Should(HaveKeyWithValue("$unset", bson.M{"random": ""})) - Expect(len(revert)).To(Equal(1)) - Expect(revert[0]).Should(HaveKeyWithValue("$set", bson.M{"random": map[string]interface{}{"extra": true}})) - }) - It("allow for removing deeply nested properties", func() { - datumObject := getBSONData(test.AutomatedBasalTandem) - incomingObject := getRawData(test.AutomatedBasalTandem) - - ofThings := map[string]interface{}{ - "of": map[string]interface{}{ - "things": map[string]interface{}{ - "go": map[string]interface{}{ - "here": true}}}} - incomingObject["lots"] = ofThings - apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) - Expect(err).To(BeNil()) - Expect(len(apply)).To(Equal(1)) - Expect(apply[0]).Should(HaveKeyWithValue("$unset", bson.M{"lots": ""})) - Expect(len(revert)).To(Equal(1)) - Expect(revert[0]).Should(HaveKeyWithValue("$set", bson.M{"lots": ofThings})) - }) - It("allow for updating nested array properties", func() { - datumObject := getBSONData(test.PumpSettingsTandem) - incomingObject := getRawData(test.PumpSettingsTandem) - - datumObject["insulinSensitivities"] = map[string]interface{}{ - "Simple": []map[string]interface{}{ - {"amount": 1.2, "start": 0}, - {"amount": 2.6, "start": 46800000}, - }, - "Standard": []map[string]interface{}{ - {"amount": 2.7753739955227665, "start": 1000}, - {"amount": 2.7753739955227665, "start": 46800000}, - }, - } - - apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) - log.Printf("err %v", err) - Expect(err).To(BeNil()) - Expect(len(apply)).To(Equal(1)) - Expect(apply[0]).Should(HaveKeyWithValue("$set", bson.M{ - "insulinSensitivities.Simple.0.amount": 1.2, - "insulinSensitivities.Simple.1.amount": 2.6, - "insulinSensitivities.Standard.0.start": float64(1000), - })) - Expect(len(revert)).To(Equal(1)) - Expect(revert[0]).Should(HaveKeyWithValue("$set", bson.M{ - "insulinSensitivities.Simple.0.amount": 2.7753739955227665, - "insulinSensitivities.Simple.1.amount": 2.7753739955227665, - "insulinSensitivities.Standard.0.start": float64(0), - })) - }) - It("no difference when inner payload changes", func() { - datumObject := getBSONData(test.AutomatedBasalTandem) - incomingObject := getRawData(test.AutomatedBasalTandem) - datumObject["payload"] = map[string]interface{}{"stuff": true} - apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) - Expect(err).To(BeNil()) - Expect(apply).To(Equal([]bson.M{})) - Expect(revert).To(Equal([]bson.M{})) - }) - It("should convert to bolusId for datum validation", func() { - bsonData := getBSONData(test.WizardTandem) - datumID := fmt.Sprintf("%v", bsonData["_id"]) - datumType := fmt.Sprintf("%v", bsonData["type"]) - apply, err := utils.ProcessDatum(datumID, datumType, bsonData) - Expect(err).To(BeNil()) - Expect(apply[1]["$unset"]).ShouldNot(HaveKey("bolusId")) + Expect(apply[0]["$set"]).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "CFDp66+LJvYW7rxf+4ndFd8hoTMq+ymzwLnuEUEqhVs="})) + Expect(apply[1]["$unset"]).Should(HaveKeyWithValue("percent", "")) + Expect(revert[0]["$unset"]).Should(HaveKeyWithValue("_deduplicator", "")) + Expect(revert[1]["$set"]).Should(HaveKeyWithValue("percent", float64(0.47857142857142865))) }) - It("should update all bgTraget values", func() { - bsonData := getBSONData(test.PumpSettingsCarelink) - datumID := fmt.Sprintf("%v", bsonData["_id"]) - datumType := fmt.Sprintf("%v", bsonData["type"]) - diff, err := utils.ProcessDatum(datumID, datumType, bsonData) + It("pump settings with blood glucose precsion updates", func() { + + bsonObject := getBSONData(test.PumpSettingsTandem) + datumID := fmt.Sprintf("%v", bsonObject["_id"]) + datumType := fmt.Sprintf("%v", bsonObject["type"]) + + apply, revert, err := utils.ProcessDatum(datumID, datumType, bsonObject) Expect(err).To(BeNil()) - Expect(diff[0]["$set"]).ToNot(BeNil()) - Expect(len(diff)).To(Equal(2)) - Expect(diff[0]["$set"]).Should(HaveKeyWithValue("units.bg", "mmol/L")) - Expect(diff[0]["$set"]).Should(HaveKeyWithValue("bgTarget.0.target", float64(0.30811))) - Expect(diff[0]["$set"]).Should(HaveKeyWithValue("bgTarget.1.target", float64(0.30811))) + Expect(apply).ToNot(BeNil()) + Expect(revert).ToNot(BeNil()) + + Expect(apply[0]["$set"]).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "bpKLJbi5JfqD7N0WJ1vj0ck03c9EZ3U0H09TCLhdd3k="})) + Expect(apply[1]["$unset"]).Should(HaveKeyWithValue("localTime", "")) + Expect(revert[0]["$unset"]).Should(HaveKeyWithValue("_deduplicator", "")) + Expect(revert[1]["$set"]).Should(HaveKeyWithValue("localTime", "2017-11-05T12:56:51.000Z")) }) }) From cc5c310613754f9027fe961308c9a04575c24cd8 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 28 Feb 2024 15:29:37 +1300 Subject: [PATCH 241/413] update targetObj setting --- .../utils/utils.go | 124 ++++++++++-------- 1 file changed, 67 insertions(+), 57 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 54db23736c..336f1441d6 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -36,7 +36,7 @@ import ( ) // NOTE: required to ensure consitent precision of bg values in the platform -func getBGValuePrecision(val float64) *float64 { +func getBGValuePrecision(val float64) float64 { //log.Printf("In VAL %v", val) floatStr := fmt.Sprintf("%v", val) if _, floatParts, found := strings.Cut(floatStr, "."); found { @@ -45,47 +45,71 @@ func getBGValuePrecision(val float64) *float64 { intValue := int(mgdlVal/glucose.MmolLToMgdLConversionFactor*glucose.MmolLToMgdLPrecisionFactor + 0.5) floatValue := float64(intValue) / glucose.MmolLToMgdLPrecisionFactor //log.Printf("Out VAL %v", floatValue) - return &floatValue + return floatValue } } - return nil -} - -func getTarget(bgTarget interface{}) (*glucose.Target, error) { - dataBytes, err := json.Marshal(bgTarget) - if err != nil { - return nil, err - } - var target glucose.Target - err = json.Unmarshal(dataBytes, &target) - if err != nil { - return nil, errorsP.Newf("bgTarget %s", string(dataBytes)) - } - return &target, nil + return val } -func setGlucoseTargetPrecision(target *glucose.Target) *glucose.Target { - if bg := target.High; bg != nil { - if val := getBGValuePrecision(*bg); val != nil { - target.High = val +// func getTarget(bgTarget interface{}) (*glucose.Target, error) { +// dataBytes, err := json.Marshal(bgTarget) +// if err != nil { +// return nil, err +// } +// var target glucose.Target +// err = json.Unmarshal(dataBytes, &target) +// if err != nil { +// return nil, errorsP.Newf("bgTarget %s", string(dataBytes)) +// } +// return &target, nil +// } + +// func setGlucoseTargetPrecision(target *glucose.Target) *glucose.Target { +// if bg := target.High; bg != nil { +// if val := getBGValuePrecision(*bg); val != nil { +// target.High = val +// } +// } +// if bg := target.Low; bg != nil { +// if val := getBGValuePrecision(*bg); val != nil { +// target.Low = val +// } +// } +// if bg := target.Range; bg != nil { +// if val := getBGValuePrecision(*bg); val != nil { +// target.Range = val +// } +// } +// if low := target.Target; low != nil { +// if val := getBGValuePrecision(*low); val != nil { +// target.Target = val +// } +// } +// return target +// } + +func updateTragetPrecision(targetObj map[string]interface{}) map[string]interface{} { + if targetObj["high"] != nil { + if highVal, ok := targetObj["high"].(float64); ok { + targetObj["high"] = getBGValuePrecision(highVal) } } - if bg := target.Low; bg != nil { - if val := getBGValuePrecision(*bg); val != nil { - target.Low = val + if targetObj["low"] != nil { + if lowVal, ok := targetObj["low"].(float64); ok { + targetObj["low"] = getBGValuePrecision(lowVal) } } - if bg := target.Range; bg != nil { - if val := getBGValuePrecision(*bg); val != nil { - target.Range = val + if targetObj["range"] != nil { + if rangeVal, ok := targetObj["range"].(float64); ok { + targetObj["range"] = getBGValuePrecision(rangeVal) } } - if low := target.Target; low != nil { - if val := getBGValuePrecision(*low); val != nil { - target.Target = val + if targetObj["low"] != nil { + if targetVal, ok := targetObj["target"].(float64); ok { + targetObj["low"] = getBGValuePrecision(targetVal) } } - return target + return targetObj } func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[string]interface{}, error) { @@ -128,18 +152,14 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s updatedObject["sleepSchedules"] = &sleepScheduleMap } if bgTargetPhysicalActivity := updatedObject["bgTargetPhysicalActivity"]; bgTargetPhysicalActivity != nil { - // target, err := getTarget(bgTargetPhysicalActivity) - // if err != nil { - // return nil, err - // } - // updatedObject["bgTargetPhysicalActivity"] = *setGlucoseTargetPrecision(target) + if targetObj, ok := bgTargetPhysicalActivity.(map[string]interface{}); ok { + updatedObject["bgTargetPhysicalActivity"] = updateTragetPrecision(targetObj) + } } if bgTargetPreprandial := updatedObject["bgTargetPreprandial"]; bgTargetPreprandial != nil { - target, err := getTarget(bgTargetPreprandial) - if err != nil { - return nil, err + if targetObj, ok := bgTargetPreprandial.(map[string]interface{}); ok { + updatedObject["bgTargetPreprandial"] = updateTragetPrecision(targetObj) } - updatedObject["bgTargetPreprandial"] = *setGlucoseTargetPrecision(target) } if bgTarget := updatedObject["bgTarget"]; bgTarget != nil { //var bgTargetStartArry pump.BloodGlucoseTargetStartArray @@ -209,9 +229,7 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s units := fmt.Sprintf("%v", updatedObject["units"]) if units == glucose.MmolL || units == glucose.Mmoll { if bgVal, ok := updatedObject["value"].(float64); ok { - if val := getBGValuePrecision(bgVal); val != nil { - updatedObject["value"] = *val - } + updatedObject["value"] = getBGValuePrecision(bgVal) } } case cgm.Type: @@ -219,18 +237,14 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s if units == glucose.MmolL || units == glucose.Mmoll { if lowAlerts, ok := updatedObject["lowAlerts"].(bson.M); ok { if bgVal, ok := lowAlerts["level"].(float64); ok { - if val := getBGValuePrecision(bgVal); val != nil { - lowAlerts["level"] = *val - updatedObject["lowAlerts"] = lowAlerts - } + lowAlerts["level"] = getBGValuePrecision(bgVal) + updatedObject["lowAlerts"] = lowAlerts } } if highAlerts, ok := updatedObject["highAlerts"].(bson.M); ok { if bgVal, ok := highAlerts["level"].(float64); ok { - if val := getBGValuePrecision(bgVal); val != nil { - highAlerts["level"] = *val - updatedObject["highAlerts"] = highAlerts - } + highAlerts["level"] = getBGValuePrecision(bgVal) + updatedObject["highAlerts"] = highAlerts } } } @@ -242,16 +256,12 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s } } if bgTarget := updatedObject["bgTarget"]; bgTarget != nil { - target, err := getTarget(bgTarget) - if err != nil { - return nil, err + if targetObj, ok := bgTarget.(map[string]interface{}); ok { + updatedObject["bgTarget"] = updateTragetPrecision(targetObj) } - updatedObject["bgTarget"] = setGlucoseTargetPrecision(target) } if bgInput, ok := updatedObject["bgInput"].(float64); ok { - if val := getBGValuePrecision(bgInput); val != nil { - updatedObject["bgInput"] = *val - } + updatedObject["bgInput"] = getBGValuePrecision(bgInput) } case device.Type: subType := fmt.Sprintf("%v", updatedObject["subType"]) From 81dd29d46b361bfa46c84fc91a1190c57aeabff7 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 28 Feb 2024 17:30:47 +1300 Subject: [PATCH 242/413] fix for wizard target types --- .../utils/test/data.go | 6 + .../utils/test/test.json | 0 .../utils/utils.go | 142 +++++------------- .../utils/utils_test.go | 28 ++++ 4 files changed, 71 insertions(+), 105 deletions(-) create mode 100644 migrations/20231128_jellyfish_migration/utils/test/test.json diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go index 6e4671e801..d40badb519 100644 --- a/migrations/20231128_jellyfish_migration/utils/test/data.go +++ b/migrations/20231128_jellyfish_migration/utils/test/data.go @@ -218,6 +218,12 @@ func tandemWizardDatum() map[string]interface{} { "rate": 0.7, } + datum["bgInput"] = 4.440598392836427 + + datum["bgTarget"] = map[string]interface{}{ + "target": 4.440598392836427, + } + datum["units"] = "mmol/L" datum["duration"] = 300000 datum["rate"] = 0.335 diff --git a/migrations/20231128_jellyfish_migration/utils/test/test.json b/migrations/20231128_jellyfish_migration/utils/test/test.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 336f1441d6..057b80b58a 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -37,58 +37,35 @@ import ( // NOTE: required to ensure consitent precision of bg values in the platform func getBGValuePrecision(val float64) float64 { - //log.Printf("In VAL %v", val) floatStr := fmt.Sprintf("%v", val) if _, floatParts, found := strings.Cut(floatStr, "."); found { if len(floatParts) > 5 { mgdlVal := val * glucose.MmolLToMgdLConversionFactor intValue := int(mgdlVal/glucose.MmolLToMgdLConversionFactor*glucose.MmolLToMgdLPrecisionFactor + 0.5) floatValue := float64(intValue) / glucose.MmolLToMgdLPrecisionFactor - //log.Printf("Out VAL %v", floatValue) return floatValue } } return val } -// func getTarget(bgTarget interface{}) (*glucose.Target, error) { -// dataBytes, err := json.Marshal(bgTarget) -// if err != nil { -// return nil, err -// } -// var target glucose.Target -// err = json.Unmarshal(dataBytes, &target) -// if err != nil { -// return nil, errorsP.Newf("bgTarget %s", string(dataBytes)) -// } -// return &target, nil -// } - -// func setGlucoseTargetPrecision(target *glucose.Target) *glucose.Target { -// if bg := target.High; bg != nil { -// if val := getBGValuePrecision(*bg); val != nil { -// target.High = val -// } -// } -// if bg := target.Low; bg != nil { -// if val := getBGValuePrecision(*bg); val != nil { -// target.Low = val -// } -// } -// if bg := target.Range; bg != nil { -// if val := getBGValuePrecision(*bg); val != nil { -// target.Range = val -// } -// } -// if low := target.Target; low != nil { -// if val := getBGValuePrecision(*low); val != nil { -// target.Target = val -// } -// } -// return target -// } +func copyMap(m map[string]interface{}) map[string]interface{} { + cp := make(map[string]interface{}) + for k, v := range m { + vm, ok := v.(map[string]interface{}) + if ok { + cp[k] = copyMap(vm) + } else { + cp[k] = v + } + } + return cp +} func updateTragetPrecision(targetObj map[string]interface{}) map[string]interface{} { + + log.Printf("traget obj %v", targetObj) + if targetObj["high"] != nil { if highVal, ok := targetObj["high"].(float64); ok { targetObj["high"] = getBGValuePrecision(highVal) @@ -104,17 +81,19 @@ func updateTragetPrecision(targetObj map[string]interface{}) map[string]interfac targetObj["range"] = getBGValuePrecision(rangeVal) } } - if targetObj["low"] != nil { + if targetObj["target"] != nil { if targetVal, ok := targetObj["target"].(float64); ok { - targetObj["low"] = getBGValuePrecision(targetVal) + targetObj["target"] = getBGValuePrecision(targetVal) } } + + log.Printf("updated traget obj %v", targetObj) return targetObj } func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[string]interface{}, error) { - updatedObject := incomingObject + updatedObject := copyMap(incomingObject) switch b.datumType { case pump.Type: @@ -149,7 +128,7 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s schedule.Days = &updatedDays sleepScheduleMap[scheduleNames[i]] = schedule } - updatedObject["sleepSchedules"] = &sleepScheduleMap + updatedObject["sleepSchedules"] = sleepScheduleMap } if bgTargetPhysicalActivity := updatedObject["bgTargetPhysicalActivity"]; bgTargetPhysicalActivity != nil { if targetObj, ok := bgTargetPhysicalActivity.(map[string]interface{}); ok { @@ -162,67 +141,13 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s } } if bgTarget := updatedObject["bgTarget"]; bgTarget != nil { - //var bgTargetStartArry pump.BloodGlucoseTargetStartArray - dataBytes, err := json.Marshal(bgTarget) - if err != nil { - return nil, err - } - log.Printf("## bgTarget %s", string(dataBytes)) - // err = json.Unmarshal(dataBytes, &bgTargetStartArry) - // if err != nil { - // return nil, errorsP.Newf("bgTarget %s", string(dataBytes)) - // } - - // for i, item := range bgTargetStartArry { - // log.Printf("## bgTargetStartArray %d %v", i, item.Target) - - // target := setGlucoseTargetPrecision(&item.Target) - - // log.Printf("## updated target %v", *target.Target) - - // bgTargetStartArry[i].Target = *target - - // log.Printf("## updated target %v", *bgTargetStartArry[i].Target.Target) - // } - - // updatedObject["bgTarget"] = bgTargetStartArry + log.Printf("## TODO [%s] bgTarget %v", b.datumType, bgTarget) } if bgTargets := updatedObject["bgTargets"]; bgTargets != nil { - //var data pump.BloodGlucoseTargetStartArrayMap - dataBytes, err := json.Marshal(bgTargets) - if err != nil { - return nil, err - } - log.Printf("## bgTargets %s", string(dataBytes)) - // err = json.Unmarshal(dataBytes, &data) - // if err != nil { - // return nil, err - // } - - // for i, d := range data { - // for x, t := range *d { - // t.Target = *setGlucoseTargetPrecision(&t.Target) - // (*d)[x] = t - // } - // data[i] = d - // } - // log.Print("## setting updated targets") - // updatedObject["bgTargets"] = data + log.Printf("## TODO [%s] bgTargets %v", b.datumType, bgTargets) } if overridePresets := updatedObject["overridePresets"]; overridePresets != nil { - // var overridePresetMap pump.OverridePresetMap - // dataBytes, err := json.Marshal(overridePresets) - // if err != nil { - // return nil, err - // } - // err = json.Unmarshal(dataBytes, &overridePresetMap) - // if err != nil { - // return nil, err - // } - // for i, p := range overridePresetMap { - // overridePresetMap[i].BloodGlucoseTarget = setGlucoseTargetPrecision(p.BloodGlucoseTarget) - // } - // updatedObject["overridePresets"] = &overridePresetMap + log.Printf("## TODO [%s] overridePresets %v", b.datumType, overridePresets) } case selfmonitored.Type, ketone.Type, continuous.Type: @@ -255,10 +180,8 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s delete(updatedObject, "bolus") } } - if bgTarget := updatedObject["bgTarget"]; bgTarget != nil { - if targetObj, ok := bgTarget.(map[string]interface{}); ok { - updatedObject["bgTarget"] = updateTragetPrecision(targetObj) - } + if bgTargetObj, ok := updatedObject["bgTarget"].(map[string]interface{}); ok { + updatedObject["bgTarget"] = updateTragetPrecision(bgTargetObj) } if bgInput, ok := updatedObject["bgInput"].(float64); ok { updatedObject["bgInput"] = getBGValuePrecision(bgInput) @@ -402,8 +325,6 @@ func (b *builder) datumChanges(storedObj map[string]interface{}) ([]bson.M, []bs return nil, nil, err } - // log.Printf("datum: %s", string(datumJSON)) - datumObject := map[string]interface{}{} if err := json.Unmarshal(datumJSON, &datumObject); err != nil { return nil, nil, err @@ -436,6 +357,17 @@ func (b *builder) datumChanges(storedObj map[string]interface{}) ([]bson.M, []bs delete(datumObject, key) } + // debug + // if b.datumType == pump.Type { + // log.Printf("pump datum: %s", string(datumJSON)) + + // storedJSON, err := json.Marshal(storedObj) + // if err != nil { + // return nil, nil, err + // } + // log.Printf("pump stored: %s", string(storedJSON)) + // } + changelog, err := diff.Diff(storedObj, datumObject, diff.StructMapKeySupport()) if err != nil { return nil, nil, err diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index adcd4d93c1..b9e55f22a5 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -556,11 +556,39 @@ var _ = Describe("back-37", func() { Expect(revert).ToNot(BeNil()) Expect(apply[0]["$set"]).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "bpKLJbi5JfqD7N0WJ1vj0ck03c9EZ3U0H09TCLhdd3k="})) + //Expect(apply[0]["$set"]).Should(HaveKeyWithValue("bgTargets.Simple.1.target", 0)) Expect(apply[1]["$unset"]).Should(HaveKeyWithValue("localTime", "")) Expect(revert[0]["$unset"]).Should(HaveKeyWithValue("_deduplicator", "")) Expect(revert[1]["$set"]).Should(HaveKeyWithValue("localTime", "2017-11-05T12:56:51.000Z")) }) + It("wizard with bgInput and bgTarget glucose updates", func() { + + bsonObject := getBSONData(test.WizardTandem) + datumID := fmt.Sprintf("%v", bsonObject["_id"]) + datumType := fmt.Sprintf("%v", bsonObject["type"]) + + apply, revert, err := utils.ProcessDatum(datumID, datumType, bsonObject) + Expect(err).To(BeNil()) + Expect(apply).ToNot(BeNil()) + Expect(revert).ToNot(BeNil()) + + applySet := apply[0]["$set"] + applyUnset := apply[1]["$unset"] + + revertSet := revert[1]["$set"] + revertUnset := revert[0]["$unset"] + + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "o6ybZQtDZ95FvuV0zYGphri2SIGesbLCbkHxc1wbbEE="})) + Expect(applySet).Should(HaveKeyWithValue("bgInput", 4.4406)) + Expect(applySet).Should(HaveKeyWithValue("bgTarget.target", 4.4406)) + Expect(applyUnset).Should(HaveKeyWithValue("localTime", "")) + Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + Expect(revertSet).Should(HaveKeyWithValue("localTime", "2017-11-05T12:56:51.000Z")) + Expect(revertSet).Should(HaveKeyWithValue("bgInput", 4.440598392836427)) + Expect(revertSet).Should(HaveKeyWithValue("bgTarget.target", 4.440598392836427)) + }) + }) }) }) From 015a5745814385954d6b5548815f0f249dafe412 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 28 Feb 2024 18:08:51 +1300 Subject: [PATCH 243/413] logging --- .../utils/utils.go | 19 ++++++++++------- .../utils/utils_test.go | 21 +++++++++++++++++++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 057b80b58a..c4aed841f4 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -63,9 +63,6 @@ func copyMap(m map[string]interface{}) map[string]interface{} { } func updateTragetPrecision(targetObj map[string]interface{}) map[string]interface{} { - - log.Printf("traget obj %v", targetObj) - if targetObj["high"] != nil { if highVal, ok := targetObj["high"].(float64); ok { targetObj["high"] = getBGValuePrecision(highVal) @@ -86,8 +83,6 @@ func updateTragetPrecision(targetObj map[string]interface{}) map[string]interfac targetObj["target"] = getBGValuePrecision(targetVal) } } - - log.Printf("updated traget obj %v", targetObj) return targetObj } @@ -141,13 +136,21 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s } } if bgTarget := updatedObject["bgTarget"]; bgTarget != nil { - log.Printf("## TODO [%s] bgTarget %v", b.datumType, bgTarget) + log.Printf("## TODO [%s] bgTarget %#v", b.datumType, bgTarget) + // if targetObjs, ok := bgTarget.([]interface{}); ok { + // for i, target := range targetObjs { + // if targetObj, ok := target.(map[string]interface{}); ok { + // targetObjs[i] = updateTragetPrecision(targetObj) + // } + // } + // updatedObject["bgTarget"] = targetObjs + // } } if bgTargets := updatedObject["bgTargets"]; bgTargets != nil { - log.Printf("## TODO [%s] bgTargets %v", b.datumType, bgTargets) + log.Printf("## TODO [%s] bgTargets %#v", b.datumType, bgTargets) } if overridePresets := updatedObject["overridePresets"]; overridePresets != nil { - log.Printf("## TODO [%s] overridePresets %v", b.datumType, overridePresets) + log.Printf("## TODO [%s] overridePresets %#v", b.datumType, overridePresets) } case selfmonitored.Type, ketone.Type, continuous.Type: diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index b9e55f22a5..374748a7ed 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -589,6 +589,27 @@ var _ = Describe("back-37", func() { Expect(revertSet).Should(HaveKeyWithValue("bgTarget.target", 4.440598392836427)) }) + It("pump settings with bgTraget glucose updates", func() { + + bsonObject := getBSONData(test.PumpSettingsCarelink) + datumID := fmt.Sprintf("%v", bsonObject["_id"]) + datumType := fmt.Sprintf("%v", bsonObject["type"]) + + apply, revert, err := utils.ProcessDatum(datumID, datumType, bsonObject) + Expect(err).To(BeNil()) + Expect(apply).ToNot(BeNil()) + Expect(revert).ToNot(BeNil()) + + applySet := apply[0]["$set"] + revertUnset := revert[0]["$unset"] + + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "NC17pw1UAaab50iChhQXJ+N9dTi6GduTy9UjsMHolow="})) + //TODO sort nested bgTarget + //Expect(applySet).Should(HaveKeyWithValue("bgTarget.0.target", 4.4406)) + //Expect(applySet).Should(HaveKeyWithValue("bgTarget.1.target", 4.4406)) + Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + }) + }) }) }) From 03b7482c458b648f913817f230c7f3bcc1119e2d Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 29 Feb 2024 09:46:47 +1300 Subject: [PATCH 244/413] fix when units are invalid --- .../utils/test/test.json | 0 .../utils/utils.go | 67 ++++++++++++------- .../utils/utils_test.go | 10 ++- 3 files changed, 48 insertions(+), 29 deletions(-) delete mode 100644 migrations/20231128_jellyfish_migration/utils/test/test.json diff --git a/migrations/20231128_jellyfish_migration/utils/test/test.json b/migrations/20231128_jellyfish_migration/utils/test/test.json deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index c4aed841f4..6ca83b4de0 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -49,17 +49,16 @@ func getBGValuePrecision(val float64) float64 { return val } -func copyMap(m map[string]interface{}) map[string]interface{} { - cp := make(map[string]interface{}) - for k, v := range m { - vm, ok := v.(map[string]interface{}) - if ok { - cp[k] = copyMap(vm) - } else { - cp[k] = v - } +func deepCopy(src map[string]interface{}, dest map[string]interface{}) error { + jsonStr, err := json.Marshal(src) + if err != nil { + return err + } + err = json.Unmarshal(jsonStr, &dest) + if err != nil { + return err } - return cp + return nil } func updateTragetPrecision(targetObj map[string]interface{}) map[string]interface{} { @@ -88,11 +87,18 @@ func updateTragetPrecision(targetObj map[string]interface{}) map[string]interfac func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[string]interface{}, error) { - updatedObject := copyMap(incomingObject) - + updatedObject := map[string]interface{}{} + err := deepCopy(incomingObject, updatedObject) + if err != nil { + return nil, err + } switch b.datumType { case pump.Type: + if units, ok := updatedObject["units"].(map[string]interface{}); ok { + units["bg"] = glucose.MmolL + } + if boluses := updatedObject["bolus"]; boluses != nil { // NOTE: fix mis-named boluses which were saved in jellyfish as a `bolus` updatedObject["boluses"] = boluses @@ -136,15 +142,13 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s } } if bgTarget := updatedObject["bgTarget"]; bgTarget != nil { - log.Printf("## TODO [%s] bgTarget %#v", b.datumType, bgTarget) - // if targetObjs, ok := bgTarget.([]interface{}); ok { - // for i, target := range targetObjs { - // if targetObj, ok := target.(map[string]interface{}); ok { - // targetObjs[i] = updateTragetPrecision(targetObj) - // } - // } - // updatedObject["bgTarget"] = targetObjs - // } + if targetObjs, ok := bgTarget.([]interface{}); ok { + for i, target := range targetObjs { + if targetObj, ok := target.(map[string]interface{}); ok { + targetObjs[i] = updateTragetPrecision(targetObj) + } + } + } } if bgTargets := updatedObject["bgTargets"]; bgTargets != nil { log.Printf("## TODO [%s] bgTargets %#v", b.datumType, bgTargets) @@ -177,6 +181,11 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s } } case calculator.Type: + + if units := fmt.Sprintf("%v", updatedObject["units"]); units != glucose.MmolL { + updatedObject["units"] = glucose.MmolL + } + if bolus := updatedObject["bolus"]; bolus != nil { // NOTE: we are doing this to ensure that the `bolus` is just a string reference if _, ok := bolus.(string); ok { @@ -283,6 +292,11 @@ func (b *builder) buildDatum(obj map[string]interface{}) error { validator.Float64("rate", parser.Float64("rate")) validator.Int("duration", parser.Int("duration")) validator.String("bolusId", parser.String("bolusId")) + // case pump.Type: + // pumpObj := (*datum).(*pump.Pump) + // for i, v := range *pumpObj.BloodGlucoseTargetSchedule { + // log.Printf("BloodGlucoseTargetSchedule %d %#v", i, *v.Target.Target) + // } } parser.NotParsed() @@ -362,13 +376,14 @@ func (b *builder) datumChanges(storedObj map[string]interface{}) ([]bson.M, []bs // debug // if b.datumType == pump.Type { - // log.Printf("pump datum: %s", string(datumJSON)) + // if datumObject["bgTarget"] != nil { + // log.Printf("pump datum: %v", datumObject["bgTarget"]) + // log.Print(string(datumJSON)) + // } - // storedJSON, err := json.Marshal(storedObj) - // if err != nil { - // return nil, nil, err + // if storedObj["bgTarget"] != nil { + // log.Printf("store datum: %v", storedObj["bgTarget"]) // } - // log.Printf("pump stored: %s", string(storedJSON)) // } changelog, err := diff.Diff(storedObj, datumObject, diff.StructMapKeySupport()) diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 374748a7ed..34a15cd34f 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -602,12 +602,16 @@ var _ = Describe("back-37", func() { applySet := apply[0]["$set"] revertUnset := revert[0]["$unset"] + revertSet := revert[1]["$set"] Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "NC17pw1UAaab50iChhQXJ+N9dTi6GduTy9UjsMHolow="})) - //TODO sort nested bgTarget - //Expect(applySet).Should(HaveKeyWithValue("bgTarget.0.target", 4.4406)) - //Expect(applySet).Should(HaveKeyWithValue("bgTarget.1.target", 4.4406)) + Expect(applySet).Should(HaveKeyWithValue("bgTarget.0.target", 5.55075)) + Expect(applySet).Should(HaveKeyWithValue("bgTarget.1.target", 5.55075)) + Expect(applySet).Should(HaveKeyWithValue("units.bg", "mmol/L")) Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + Expect(revertSet).Should(HaveKeyWithValue("bgTarget.0.target", 5.550747991045533)) + Expect(revertSet).Should(HaveKeyWithValue("bgTarget.1.target", 5.550747991045533)) + Expect(revertSet).Should(HaveKeyWithValue("units.bg", "mg/dL")) }) }) From 3fbb9356c0d6d8ee35fba5bac9f0c16ee6bb7b22 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 29 Feb 2024 12:23:31 +1300 Subject: [PATCH 245/413] write revert data for each datum --- .../utils/migrationUtil.go | 32 +- .../utils/utils.go | 43 +- .../utils/utils_test.go | 592 ++---------------- 3 files changed, 74 insertions(+), 593 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 56ed8629bd..ef171c9efe 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -153,18 +153,28 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe } m.GetStats().report() m.writeErrors(nil) - m.writeDiff(nil) + m.writeAudit(nil) return nil } -func (m *migrationUtil) SetUpdates(data UpdateData) { - m.groupedDiffs[data.ItemType] = append(m.groupedDiffs[data.ItemType], data) - for _, u := range data.Apply { +func (d UpdateData) getMongoUpdates() []mongo.WriteModel { + updates := []mongo.WriteModel{} + for _, u := range d.Apply { updateOp := mongo.NewUpdateOneModel() - updateOp.Filter = data.Filter + updateOp.Filter = d.Filter updateOp.SetUpdate(u) - m.updates = append(m.updates, updateOp) + updates = append(updates, updateOp) } + updateOp := mongo.NewUpdateOneModel() + updateOp.Filter = d.Filter + updateOp.SetUpdate(bson.M{"$set": bson.M{"_jellyfishValues": d.Revert}}) + updates = append(updates, updateOp) + return updates +} + +func (m *migrationUtil) SetUpdates(data UpdateData) { + m.groupedDiffs[data.ItemType] = append(m.groupedDiffs[data.ItemType], data) + m.updates = append(m.updates, data.getMongoUpdates()...) } func (m *migrationUtil) SetLastProcessed(lastID string) { @@ -205,7 +215,7 @@ func (m *migrationUtil) writeErrors(groupLimit *int) { continue } } - f, err := createFile("logs", group, "error_%s.log") + f, err := createFile("error", group, "%s.log") if err != nil { log.Println(err) os.Exit(1) @@ -223,14 +233,14 @@ func (m *migrationUtil) writeErrors(groupLimit *int) { } } -func (m *migrationUtil) writeDiff(groupLimit *int) { +func (m *migrationUtil) writeAudit(groupLimit *int) { for group, diffs := range m.groupedDiffs { if groupLimit != nil { if len(diffs) < *groupLimit { continue } } - f, err := createFile("updates", group, "diff_%s.json") + f, err := createFile("audit", group, "%s.json") if err != nil { log.Println(err) os.Exit(1) @@ -553,12 +563,12 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio writeLimit := 500 if m.config.dryRun { log.Println("dry-run so no changes applied") - m.writeDiff(&writeLimit) + m.writeAudit(&writeLimit) } else { log.Printf("write took [%s] for [%d] items\n", time.Since(writeStart), writtenCount) m.GetStats().report() m.writeErrors(&writeLimit) - m.writeDiff(&writeLimit) + m.writeAudit(&writeLimit) } return nil } diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 6ca83b4de0..8af9fdcbac 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -61,6 +61,16 @@ func deepCopy(src map[string]interface{}, dest map[string]interface{}) error { return nil } +func updateTargets(targets interface{}) { + if targetObjs, ok := targets.([]interface{}); ok { + for i, target := range targetObjs { + if targetObj, ok := target.(map[string]interface{}); ok { + targetObjs[i] = updateTragetPrecision(targetObj) + } + } + } +} + func updateTragetPrecision(targetObj map[string]interface{}) map[string]interface{} { if targetObj["high"] != nil { if highVal, ok := targetObj["high"].(float64); ok { @@ -142,16 +152,14 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s } } if bgTarget := updatedObject["bgTarget"]; bgTarget != nil { - if targetObjs, ok := bgTarget.([]interface{}); ok { - for i, target := range targetObjs { - if targetObj, ok := target.(map[string]interface{}); ok { - targetObjs[i] = updateTragetPrecision(targetObj) - } - } - } + updateTargets(bgTarget) } if bgTargets := updatedObject["bgTargets"]; bgTargets != nil { - log.Printf("## TODO [%s] bgTargets %#v", b.datumType, bgTargets) + if targetMaps, ok := bgTargets.(map[string]interface{}); ok { + for _, targets := range targetMaps { + updateTargets(targets) + } + } } if overridePresets := updatedObject["overridePresets"]; overridePresets != nil { log.Printf("## TODO [%s] overridePresets %#v", b.datumType, overridePresets) @@ -292,11 +300,6 @@ func (b *builder) buildDatum(obj map[string]interface{}) error { validator.Float64("rate", parser.Float64("rate")) validator.Int("duration", parser.Int("duration")) validator.String("bolusId", parser.String("bolusId")) - // case pump.Type: - // pumpObj := (*datum).(*pump.Pump) - // for i, v := range *pumpObj.BloodGlucoseTargetSchedule { - // log.Printf("BloodGlucoseTargetSchedule %d %#v", i, *v.Target.Target) - // } } parser.NotParsed() @@ -374,18 +377,6 @@ func (b *builder) datumChanges(storedObj map[string]interface{}) ([]bson.M, []bs delete(datumObject, key) } - // debug - // if b.datumType == pump.Type { - // if datumObject["bgTarget"] != nil { - // log.Printf("pump datum: %v", datumObject["bgTarget"]) - // log.Print(string(datumJSON)) - // } - - // if storedObj["bgTarget"] != nil { - // log.Printf("store datum: %v", storedObj["bgTarget"]) - // } - // } - changelog, err := diff.Diff(storedObj, datumObject, diff.StructMapKeySupport()) if err != nil { return nil, nil, err @@ -445,8 +436,6 @@ func ProcessDatum(dataID string, dataType string, bsonData bson.M) ([]bson.M, [] return nil, nil, err } - // log.Printf("# FROM BSON %s", string(storedJSON)) - storedData := map[string]interface{}{} if err := json.Unmarshal(storedJSON, &storedData); err != nil { return nil, nil, err diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 34a15cd34f..02b09cd419 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -20,564 +20,57 @@ var _ = Describe("back-37", func() { return bsonData } - // var datumSetup = func(testObj map[string]interface{}) (map[string]interface{}, error) { - // bsonData := getBSONData(testObj) - // objType := fmt.Sprintf("%v", bsonData["type"]) - // utils.ApplyBaseChanges(bsonData, objType) - // incomingJSONData, err := json.Marshal(bsonData) - // if err != nil { - // return nil, err - // } - // cleanedObject := map[string]interface{}{} - // if err := json.Unmarshal(incomingJSONData, &cleanedObject); err != nil { - // return nil, err - // } - // return cleanedObject, nil - // } - - // var _ = Describe("BuildPlatformDatum", func() { - - // It("should successfully build basal datum", func() { - // Skip("todo") - // basalData, err := datumSetup(test.AutomatedBasalTandem) - // Expect(err).To(BeNil()) - // datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", basalData["_id"]), basal.Type, basalData) - // Expect(err).To(BeNil()) - // Expect(datum).ToNot(BeNil()) - // Expect((*datum).GetType()).To(Equal(basal.Type)) - // }) - // It("should successfully build dexcom g5 datum", func() { - // Skip("todo") - // cbgData, err := datumSetup(test.CBGDexcomG5MobDatum) - // Expect(err).To(BeNil()) - // datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", cbgData["_id"]), continuous.Type, cbgData) - // Expect(err).To(BeNil()) - // Expect(datum).ToNot(BeNil()) - // Expect((*datum).GetType()).To(Equal(continuous.Type)) - // }) - // It("should successfully build carelink pump settings", func() { - // Skip("todo") - // pSettingsData, err := datumSetup(test.PumpSettingsCarelink) - // Expect(err).To(BeNil()) - // datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", pSettingsData["_id"]), pump.Type, pSettingsData) - // Expect(err).To(BeNil()) - // Expect(datum).ToNot(BeNil()) - // Expect((*datum).GetType()).To(Equal(pump.Type)) - // }) - // It("should successfully build omnipod pump settings", func() { - // Skip("todo") - // pSettingsData, err := datumSetup(test.PumpSettingsOmnipod) - // Expect(err).To(BeNil()) - // datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", pSettingsData["_id"]), pump.Type, pSettingsData) - // Expect(err).To(BeNil()) - // Expect(datum).ToNot(BeNil()) - // Expect((*datum).GetType()).To(Equal(pump.Type)) - // }) - // It("should successfully build tandem pump settings", func() { - // Skip("todo") - // pSettingsData, err := datumSetup(test.PumpSettingsTandem) - // Expect(err).To(BeNil()) - // datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", pSettingsData["_id"]), pump.Type, pSettingsData) - // Expect(err).To(BeNil()) - // Expect(datum).ToNot(BeNil()) - // Expect((*datum).GetType()).To(Equal(pump.Type)) - // }) - // It("should successfully build tandem wizard", func() { - // Skip("todo") - // calcData, err := datumSetup(test.WizardTandem) - // Expect(err).To(BeNil()) - // datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", calcData["_id"]), calculator.Type, calcData) - // Expect(err).To(BeNil()) - // Expect(datum).ToNot(BeNil()) - // Expect((*datum).GetType()).To(Equal(calculator.Type)) - // }) - // It("should successfully build device event", func() { - // Skip("todo") - // deviceEventData, err := datumSetup(test.ReservoirChange) - // Expect(err).To(BeNil()) - // datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", deviceEventData["_id"]), device.Type, deviceEventData) - // Expect(err).To(BeNil()) - // Expect(datum).ToNot(BeNil()) - // Expect((*datum).GetType()).To(Equal(device.Type)) - // }) - // It("should successfully build cgm settings", func() { - // Skip("todo") - // deviceEventData, err := datumSetup(test.CGMSetting) - // Expect(err).To(BeNil()) - // datum, err := utils.BuildPlatformDatum(fmt.Sprintf("%v", deviceEventData["_id"]), cgm.Type, deviceEventData) - // Expect(err).To(BeNil()) - // Expect(datum).ToNot(BeNil()) - // Expect((*datum).GetType()).To(Equal(cgm.Type)) - // }) - // }) - - // var _ = Describe("ApplyBaseChanges", func() { - // const expectedID = "some-id" - // var pumpSettingsDatum *pump.Pump - - // BeforeEach(func() { - // mmolL := pump.DisplayBloodGlucoseUnitsMmolPerL - // pumpSettingsDatum = pumpTest.NewPump(&mmolL) - // *pumpSettingsDatum.ID = expectedID - // *pumpSettingsDatum.UserID = "some-user-id" - // *pumpSettingsDatum.DeviceID = "some-device-id" - // theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") - // *pumpSettingsDatum.Time = theTime - // }) - // Context("pumpSettings datum with mis-named jellyfish bolus", func() { - // var bolusData = &pump.BolusMap{ - // "bolus-1": pumpTest.NewRandomBolus(), - // "bolus-2": pumpTest.NewRandomBolus(), - // } - // var settingsBolusDatum bson.M - // var datumType string - - // BeforeEach(func() { - // settingsBolusDatum = getBSONData(pumpSettingsDatum) - // settingsBolusDatum["bolus"] = bolusData - // settingsBolusDatum["_id"] = expectedID - // datumType = fmt.Sprintf("%v", settingsBolusDatum["type"]) - // }) - - // It("should do nothing when has no bolus", func() { - // Skip("todo") - // settingsBolusDatum["bolus"] = nil - // Expect(settingsBolusDatum["bolus"]).To(BeNil()) - // err := utils.ApplyBaseChanges(settingsBolusDatum, datumType) - // Expect(err).To(BeNil()) - // Expect(settingsBolusDatum["bolus"]).To(BeNil()) - // Expect(settingsBolusDatum["boluses"]).To(BeNil()) - // }) - - // It("should rename as boluses when bolus found", func() { - // Skip("todo") - // Expect(settingsBolusDatum["bolus"]).ToNot(BeNil()) - // err := utils.ApplyBaseChanges(settingsBolusDatum, datumType) - // Expect(err).To(BeNil()) - // Expect(settingsBolusDatum["bolus"]).To(BeNil()) - // Expect(settingsBolusDatum["boluses"]).ToNot(BeNil()) - // Expect(settingsBolusDatum["boluses"]).To(Equal(bolusData)) - // }) - // }) - // Context("pumpSettings datum with unordered sleepSchedules", func() { - // expectedSleepSchedulesMap := &pump.SleepScheduleMap{} - // var invalidDays *pump.SleepSchedule - // var s1Days *pump.SleepSchedule - // var s2Days *pump.SleepSchedule - // var sleepSchedulesDatum bson.M - // var datumType string - - // BeforeEach(func() { - // sleepSchedulesDatum = getBSONData(pumpSettingsDatum) - // datumType = fmt.Sprintf("%v", sleepSchedulesDatum["type"]) - // s1 := pumpTest.RandomSleepSchedule() - // s2 := pumpTest.RandomSleepSchedule() - // (*expectedSleepSchedulesMap)["1"] = s1 - // (*expectedSleepSchedulesMap)["2"] = s2 - - // s1Days = pumpTest.CloneSleepSchedule(s1) - // for key, day := range *s1Days.Days { - // (*s1Days.Days)[key] = strings.ToUpper(day) - // } - // s2Days = pumpTest.CloneSleepSchedule(s2) - // for key, day := range *s2Days.Days { - // (*s2Days.Days)[key] = strings.ToUpper(day) - // } - // invalidDays = pumpTest.CloneSleepSchedule(s2) - // invalidDays.Days = &[]string{"not-a-day", common.DayFriday} - // Expect(expectedSleepSchedulesMap).ToNot(BeNil()) - // pumpSettingsDatum.SleepSchedules = nil - // sleepSchedulesDatum = getBSONData(pumpSettingsDatum) - // sleepSchedulesDatum["_id"] = expectedID - // sleepSchedulesDatum["bolus"] = nil //remove as not testing here - // }) - - // It("does nothing when no sleepSchedules", func() { - // Skip("todo") - // sleepSchedulesDatum["sleepSchedules"] = nil - // err := utils.ApplyBaseChanges(sleepSchedulesDatum, datumType) - // Expect(err).To(BeNil()) - // Expect(sleepSchedulesDatum["sleepSchedules"]).To(BeNil()) - // }) - // It("returns updated sleepSchedules when valid", func() { - // Skip("todo") - // sleepSchedulesDatum["sleepSchedules"] = []*pump.SleepSchedule{s1Days, s2Days} - // err := utils.ApplyBaseChanges(sleepSchedulesDatum, datumType) - // Expect(err).To(BeNil()) - // Expect(sleepSchedulesDatum["sleepSchedules"]).ToNot(BeNil()) - // Expect(sleepSchedulesDatum["sleepSchedules"]).To(Equal(expectedSleepSchedulesMap)) - // }) - // It("returns error when sleepSchedules have invalid days", func() { - // Skip("todo") - // sleepSchedulesDatum["sleepSchedules"] = []*pump.SleepSchedule{invalidDays} - // err := utils.ApplyBaseChanges(sleepSchedulesDatum, datumType) - // Expect(err).ToNot(BeNil()) - // Expect(err.Error()).To(Equal("pumpSettings.sleepSchedules has an invalid day of week not-a-day")) - // }) - // }) - // Context("datum with glucose", func() { - // var newContinuous = func(units *string) *continuous.Continuous { - // datum := continuous.New() - // datum.Glucose = *glucoseTest.NewGlucose(units) - // datum.Type = "cbg" - // *datum.ID = expectedID - // *datum.UserID = "some-user-id" - // *datum.DeviceID = "some-device-id" - // theTime, _ := time.Parse(time.RFC3339, "2016-09-01T11:00:00Z") - // *datum.Time = theTime - // return datum - // } - // datumType := "cbg" - // It("should do nothing when value is already correct", func() { - // Skip("todo") - // mmoll := glucose.MmolL - // cbg := newContinuous(&mmoll) - // cbgData := getBSONData(cbg) - // cbgData["_id"] = expectedID - // cbgData["value"] = 4.88466 - - // Expect(cbgData["value"]).To(Equal(4.88466)) - // err := utils.ApplyBaseChanges(cbgData, datumType) - // Expect(err).To(BeNil()) - // Expect(cbgData["value"]).To(Equal(4.88466)) - // }) - // It("should update the value when the precesion is too accurate correct", func() { - // Skip("todo") - // mmoll := glucose.MmolL - // cbg := newContinuous(&mmoll) - // cbgData := getBSONData(cbg) - // cbgData["_id"] = expectedID - // cbgData["value"] = 4.88465823212007 - - // Expect(cbgData["value"]).To(Equal(4.88465823212007)) - // err := utils.ApplyBaseChanges(cbgData, datumType) - // Expect(err).To(BeNil()) - // floatVal := 4.88466 - // Expect(cbgData["value"]).To(Equal(&floatVal)) - // }) - // }) - // Context("reservoirChange deviceEvent datum with status string", func() { - // var newReservoirChange = func() *reservoirchange.ReservoirChange { - // datum := reservoirchange.New() - // datum.Device = *dataTypesDeviceTest.RandomDevice() - // datum.SubType = "reservoirChange" - // return datum - // } - // It("should convert to statusId", func() { - // Skip("todo") - // deviceEvent := newReservoirChange() - // deviceEventData := getBSONData(deviceEvent) - // deviceEventData["status"] = "some-status-id" - // err := utils.ApplyBaseChanges(deviceEventData, deviceEvent.Type) - // Expect(err).To(BeNil()) - // Expect(deviceEventData["status"]).To(BeNil()) - // Expect(deviceEventData["statusId"]).To(Equal("some-status-id")) - // }) - // }) - // Context("wizard datum with bolus string", func() { - // It("should convert to bolusId for datum validation", func() { - // Skip("todo") - // wizardBSON := getBSONData(test.WizardTandem) - // Expect(wizardBSON["bolus"]).ToNot(BeNil()) - // err := utils.ApplyBaseChanges(wizardBSON, calculator.Type) - // Expect(err).To(BeNil()) - // Expect(wizardBSON["bolus"]).To(BeNil()) - // }) - // }) - // Context("datum with string payload", func() { - // var datumWithPayload primitive.M - // var datumType string - // var payload *metadata.Metadata - // BeforeEach(func() { - // datumWithPayload = getBSONData(pumpSettingsDatum) - // payload = metadataTest.RandomMetadata() - // datumWithPayload["payload"] = *payload - // datumType = fmt.Sprintf("%v", datumWithPayload["type"]) - // }) - - // It("should do nothing when value is already correct", func() { - // Skip("todo") - // Expect(datumWithPayload["payload"]).To(Equal(*payload)) - // err := utils.ApplyBaseChanges(datumWithPayload, datumType) - // Expect(err).To(BeNil()) - // Expect(datumWithPayload["payload"]).To(Equal(*payload)) - // }) - // It("should update the payload when it is a string", func() { - // Skip("todo") - // datumWithPayload["payload"] = `{"transmitterId":"410X6M","transmitterTicks":5796922,"trend":"flat"}` - // err := utils.ApplyBaseChanges(datumWithPayload, datumType) - // Expect(err).To(BeNil()) - // Expect(datumWithPayload["payload"]).To(Equal(&metadata.Metadata{ - // "transmitterId": "410X6M", - // "transmitterTicks": float64(5796922), - // "trend": "flat", - // })) - // }) - // It("should remove the payload when it is empty", func() { - // Skip("todo") - // datumWithPayload["payload"] = bson.M{} - // err := utils.ApplyBaseChanges(datumWithPayload, datumType) - // Expect(err).To(BeNil()) - // Expect(datumWithPayload["payload"]).To(BeNil()) - // }) - // }) - // Context("datum with string annotations", func() { - // var datumWithAnnotation primitive.M - // var annotations *metadata.MetadataArray - // var datumType string - // BeforeEach(func() { - // datumWithAnnotation = getBSONData(pumpSettingsDatum) - // annotations = metadataTest.RandomMetadataArray() - // datumWithAnnotation["annotations"] = *annotations - // datumType = fmt.Sprintf("%v", datumWithAnnotation["type"]) - // }) - - // It("should do nothing when value is already correct", func() { - // Skip("todo") - // Expect(datumWithAnnotation["annotations"]).To(Equal(*annotations)) - // err := utils.ApplyBaseChanges(datumWithAnnotation, datumType) - // Expect(err).To(BeNil()) - // Expect(datumWithAnnotation["annotations"]).To(Equal(*annotations)) - // }) - // It("should update the annotations when it is a string", func() { - // Skip("todo") - // datumWithAnnotation["annotations"] = `[{"code":"bg/out-of-range","threshold":40,"value":"low"}]` - // err := utils.ApplyBaseChanges(datumWithAnnotation, datumType) - // Expect(err).To(BeNil()) - // Expect(datumWithAnnotation["annotations"]).To(Equal(&metadata.MetadataArray{ - // &metadata.Metadata{ - // "code": "bg/out-of-range", - // "threshold": float64(40), - // "value": "low", - // }, - // })) - // }) - // }) - // }) - - // var _ = Describe("GetDatumChanges", func() { - - // const expectedID = "difference-id" - - // var getRawData = func(datum interface{}) map[string]interface{} { - // var rawObject map[string]interface{} - // asByte, _ := json.Marshal(&datum) - // json.Unmarshal(asByte, &rawObject) - // return rawObject - // } - - // It("has no difference", func() { - // Skip("Todo") - // datumObject := getBSONData(test.AutomatedBasalTandem) - // incomingObject := getRawData(test.AutomatedBasalTandem) - // apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) - // Expect(err).To(BeNil()) - // Expect(apply).ToNot(BeNil()) - // Expect(apply).To(Equal([]bson.M{})) - // Expect(revert).ToNot(BeNil()) - // Expect(revert).To(Equal([]bson.M{})) - // }) - // It("set for missing properties", func() { - // Skip("Todo") - // datumObject := getBSONData(test.AutomatedBasalTandem) - // incomingObject := getRawData(test.AutomatedBasalTandem) - // delete(incomingObject, "deliveryType") - // apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) - // Expect(err).To(BeNil()) - // Expect(apply).To(Equal([]bson.M{{"$set": bson.M{"deliveryType": "automated"}}})) - // Expect(revert).To(Equal([]bson.M{{"$unset": bson.M{"deliveryType": ""}}})) - // }) - // It("set _deduplicator correctly", func() { - // Skip("Todo") - // calcData, _ := datumSetup(test.WizardTandem) - // id := fmt.Sprintf("%v", calcData["_id"]) - // datum, _ := utils.BuildPlatformDatum(id, calculator.Type, calcData) - // apply, revert, err := utils.GetDatumChanges(id, datum, calcData) - // Expect(err).To(BeNil()) - // Expect(len(apply)).To(Equal(2)) - // Expect(apply[0]["$set"]).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "o6ybZQtDZ95FvuV0zYGphri2SIGesbLCbkHxc1wbbEE="})) - // Expect(len(revert)).To(Equal(2)) - // Expect(revert[0]).Should(HaveKeyWithValue("$unset", bson.M{"_deduplicator": ""})) - // }) - // It("unset for unwanted properties", func() { - // Skip("Todo") - // datumObject := getBSONData(test.AutomatedBasalTandem) - // incomingObject := getRawData(test.AutomatedBasalTandem) - // incomingObject["random"] = map[string]interface{}{"extra": true} - // apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) - // Expect(err).To(BeNil()) - // Expect(len(apply)).To(Equal(1)) - // Expect(apply[0]).Should(HaveKeyWithValue("$unset", bson.M{"random": ""})) - // Expect(len(revert)).To(Equal(1)) - // Expect(revert[0]).Should(HaveKeyWithValue("$set", bson.M{"random": map[string]interface{}{"extra": true}})) - // }) - // It("allow for removing deeply nested properties", func() { - // Skip("Todo") - // datumObject := getBSONData(test.AutomatedBasalTandem) - // incomingObject := getRawData(test.AutomatedBasalTandem) - - // ofThings := map[string]interface{}{ - // "of": map[string]interface{}{ - // "things": map[string]interface{}{ - // "go": map[string]interface{}{ - // "here": true}}}} - // incomingObject["lots"] = ofThings - // apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) - // Expect(err).To(BeNil()) - // Expect(len(apply)).To(Equal(1)) - // Expect(apply[0]).Should(HaveKeyWithValue("$unset", bson.M{"lots": ""})) - // Expect(len(revert)).To(Equal(1)) - // Expect(revert[0]).Should(HaveKeyWithValue("$set", bson.M{"lots": ofThings})) - // }) - // It("allow for updating nested array properties", func() { - // Skip("Todo") - // datumObject := getBSONData(test.PumpSettingsTandem) - // incomingObject := getRawData(test.PumpSettingsTandem) - - // datumObject["insulinSensitivities"] = map[string]interface{}{ - // "Simple": []map[string]interface{}{ - // {"amount": 1.2, "start": 0}, - // {"amount": 2.6, "start": 46800000}, - // }, - // "Standard": []map[string]interface{}{ - // {"amount": 2.7753739955227665, "start": 1000}, - // {"amount": 2.7753739955227665, "start": 46800000}, - // }, - // } - - // apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) - // Expect(err).To(BeNil()) - // Expect(len(apply)).To(Equal(1)) - // Expect(apply[0]).Should(HaveKeyWithValue("$set", bson.M{ - // "insulinSensitivities.Simple.0.amount": 1.2, - // "insulinSensitivities.Simple.1.amount": 2.6, - // "insulinSensitivities.Standard.0.start": float64(1000), - // })) - // Expect(len(revert)).To(Equal(1)) - // Expect(revert[0]).Should(HaveKeyWithValue("$set", bson.M{ - // "insulinSensitivities.Simple.0.amount": 2.7753739955227665, - // "insulinSensitivities.Simple.1.amount": 2.7753739955227665, - // "insulinSensitivities.Standard.0.start": float64(0), - // })) - // }) - // It("no difference when inner payload changes", func() { - // Skip("Todo") - // datumObject := getBSONData(test.AutomatedBasalTandem) - // incomingObject := getRawData(test.AutomatedBasalTandem) - // datumObject["payload"] = map[string]interface{}{"stuff": true} - // apply, revert, err := utils.GetDatumChanges(expectedID, datumObject, incomingObject) - // Expect(err).To(BeNil()) - // Expect(apply).To(Equal([]bson.M{})) - // Expect(revert).To(Equal([]bson.M{})) - // }) - - // It("should convert to bolusId for datum validation", func() { - // Skip("Todo") - // bsonData := getBSONData(test.WizardTandem) - // datumID := fmt.Sprintf("%v", bsonData["_id"]) - // datumType := fmt.Sprintf("%v", bsonData["type"]) - // apply, _, err := utils.ProcessDatum(datumID, datumType, bsonData) - // Expect(err).To(BeNil()) - // Expect(apply[1]["$unset"]).ShouldNot(HaveKey("bolusId")) - // }) - - // It("should update all bgTraget values", func() { - - // bsonObject := getBSONData(test.PumpSettingsCarelink) - // datumID := fmt.Sprintf("%v", bsonObject["_id"]) - // datumType := fmt.Sprintf("%v", bsonObject["type"]) - // apply, revert, err := utils.ProcessDatum(datumID, datumType, bsonObject) - - // Expect(err).To(BeNil()) - // Expect(apply[0]["$set"]).ToNot(BeNil()) - // Expect(len(apply)).To(Equal(2)) - // Expect(apply[0]["$set"]).Should(HaveKeyWithValue("units.bg", "mmol/L")) - // Expect(apply[0]["$set"]).Should(HaveKeyWithValue("bgTarget.0.target", float64(5.55074))) - // Expect(apply[0]["$set"]).Should(HaveKeyWithValue("bgTarget.1.target", float64(5.55074))) - - // Expect(revert[0]["$set"]).ToNot(BeNil()) - // Expect(len(revert)).To(Equal(2)) - // Expect(revert[0]["$set"]).Should(HaveKeyWithValue("units.bg", "mmol/L")) - // Expect(revert[0]["$set"]).Should(HaveKeyWithValue("bgTarget.0.target", float64(5.550747991045533))) - // Expect(revert[0]["$set"]).Should(HaveKeyWithValue("bgTarget.1.target", float64(5.550747991045533))) - // }) - - // It("pump settings omnipod", func() { - // Skip("Todo") - // incomingObject := getRawData(test.PumpSettingsOmnipod) - // datumID := fmt.Sprintf("%v", incomingObject["_id"]) - // datum, _ := utils.BuildPlatformDatum(datumID, pump.Type, incomingObject) - // apply, revert, err := utils.GetDatumChanges(datumID, datum, incomingObject) - // Expect(err).To(BeNil()) - // Expect(len(apply)).To(Equal(2)) - // Expect(apply[0]["$set"]).Should(HaveKeyWithValue("units.bg", "mmol/L")) - // Expect(apply[0]["$set"]).Should(HaveKeyWithValue("bgTarget.0.high", float64(0.40054))) - // Expect(apply[0]["$set"]).Should(HaveKeyWithValue("bgTarget.1.high", float64(0.40054))) - // Expect(apply[0]["$set"]).Should(HaveKeyWithValue("bgTarget.0.target", float64(0.30811))) - // Expect(apply[0]["$set"]).Should(HaveKeyWithValue("bgTarget.1.target", float64(0.30811))) - // Expect(len(revert)).To(Equal(2)) - // Expect(revert[0]["$set"]).Should(HaveKeyWithValue("units.bg", "mmol/L")) - // Expect(revert[0]["$set"]).Should(HaveKeyWithValue("bgTarget.0.high", float64(0.40054))) - // Expect(revert[0]["$set"]).Should(HaveKeyWithValue("bgTarget.1.high", float64(0.40054))) - // Expect(revert[0]["$set"]).Should(HaveKeyWithValue("bgTarget.0.target", float64(0.30811))) - // Expect(revert[0]["$set"]).Should(HaveKeyWithValue("bgTarget.1.target", float64(0.30811))) - // }) - - // }) + var setup = func(bsonObj bson.M) (applySet interface{}, applyUnset interface{}, revertUnset interface{}, revertSet interface{}) { + datumType := fmt.Sprintf("%v", bsonObj["type"]) + datumID := fmt.Sprintf("%v", bsonObj["_id"]) + apply, revert, err := utils.ProcessDatum(datumID, datumType, bsonObj) + Expect(err).To(BeNil()) + Expect(apply).ToNot(BeNil()) + Expect(revert).ToNot(BeNil()) + + applySet = apply[0]["$set"] + applyUnset = apply[1]["$unset"] + revertUnset = revert[0]["$unset"] + revertSet = revert[1]["$set"] + + return applySet, applyUnset, revertUnset, revertSet + } var _ = Describe("ProcessDatum", func() { It("basal with unwanted percent feild", func() { - bsonObject := getBSONData(test.AutomatedBasalTandem) - datumID := fmt.Sprintf("%v", bsonObject["_id"]) - datumType := fmt.Sprintf("%v", bsonObject["type"]) - - apply, revert, err := utils.ProcessDatum(datumID, datumType, bsonObject) - Expect(err).To(BeNil()) - Expect(apply).ToNot(BeNil()) - Expect(revert).ToNot(BeNil()) + applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.AutomatedBasalTandem)) - Expect(apply[0]["$set"]).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "CFDp66+LJvYW7rxf+4ndFd8hoTMq+ymzwLnuEUEqhVs="})) - Expect(apply[1]["$unset"]).Should(HaveKeyWithValue("percent", "")) - Expect(revert[0]["$unset"]).Should(HaveKeyWithValue("_deduplicator", "")) - Expect(revert[1]["$set"]).Should(HaveKeyWithValue("percent", float64(0.47857142857142865))) + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "CFDp66+LJvYW7rxf+4ndFd8hoTMq+ymzwLnuEUEqhVs="})) + Expect(applyUnset).Should(HaveKeyWithValue("percent", "")) + Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + Expect(revertSet).Should(HaveKeyWithValue("percent", float64(0.47857142857142865))) }) It("pump settings with blood glucose precsion updates", func() { - bsonObject := getBSONData(test.PumpSettingsTandem) - datumID := fmt.Sprintf("%v", bsonObject["_id"]) - datumType := fmt.Sprintf("%v", bsonObject["type"]) - - apply, revert, err := utils.ProcessDatum(datumID, datumType, bsonObject) - Expect(err).To(BeNil()) - Expect(apply).ToNot(BeNil()) - Expect(revert).ToNot(BeNil()) + applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.PumpSettingsTandem)) - Expect(apply[0]["$set"]).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "bpKLJbi5JfqD7N0WJ1vj0ck03c9EZ3U0H09TCLhdd3k="})) - //Expect(apply[0]["$set"]).Should(HaveKeyWithValue("bgTargets.Simple.1.target", 0)) - Expect(apply[1]["$unset"]).Should(HaveKeyWithValue("localTime", "")) - Expect(revert[0]["$unset"]).Should(HaveKeyWithValue("_deduplicator", "")) - Expect(revert[1]["$set"]).Should(HaveKeyWithValue("localTime", "2017-11-05T12:56:51.000Z")) + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "bpKLJbi5JfqD7N0WJ1vj0ck03c9EZ3U0H09TCLhdd3k="})) + Expect(applySet).Should(HaveKeyWithValue("bgTargets.Simple.0.target", 5.55075)) + Expect(applySet).Should(HaveKeyWithValue("bgTargets.Simple.1.target", 5.55075)) + Expect(applySet).Should(HaveKeyWithValue("bgTargets.Standard.0.target", 5.55075)) + Expect(applySet).Should(HaveKeyWithValue("bgTargets.Standard.1.target", 5.55075)) + Expect(applySet).Should(HaveKeyWithValue("units.bg", "mmol/L")) + Expect(applyUnset).Should(HaveKeyWithValue("localTime", "")) + Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + Expect(revertSet).Should(HaveKeyWithValue("localTime", "2017-11-05T12:56:51.000Z")) + Expect(revertSet).Should(HaveKeyWithValue("bgTargets.Simple.0.target", 5.550747991045533)) + Expect(revertSet).Should(HaveKeyWithValue("bgTargets.Simple.1.target", 5.550747991045533)) + Expect(revertSet).Should(HaveKeyWithValue("bgTargets.Standard.0.target", 5.550747991045533)) + Expect(revertSet).Should(HaveKeyWithValue("bgTargets.Standard.1.target", 5.550747991045533)) + Expect(revertSet).Should(HaveKeyWithValue("units.bg", "mg/dL")) }) It("wizard with bgInput and bgTarget glucose updates", func() { - bsonObject := getBSONData(test.WizardTandem) - datumID := fmt.Sprintf("%v", bsonObject["_id"]) - datumType := fmt.Sprintf("%v", bsonObject["type"]) - - apply, revert, err := utils.ProcessDatum(datumID, datumType, bsonObject) - Expect(err).To(BeNil()) - Expect(apply).ToNot(BeNil()) - Expect(revert).ToNot(BeNil()) - - applySet := apply[0]["$set"] - applyUnset := apply[1]["$unset"] - - revertSet := revert[1]["$set"] - revertUnset := revert[0]["$unset"] + applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.WizardTandem)) Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "o6ybZQtDZ95FvuV0zYGphri2SIGesbLCbkHxc1wbbEE="})) Expect(applySet).Should(HaveKeyWithValue("bgInput", 4.4406)) @@ -591,18 +84,7 @@ var _ = Describe("back-37", func() { It("pump settings with bgTraget glucose updates", func() { - bsonObject := getBSONData(test.PumpSettingsCarelink) - datumID := fmt.Sprintf("%v", bsonObject["_id"]) - datumType := fmt.Sprintf("%v", bsonObject["type"]) - - apply, revert, err := utils.ProcessDatum(datumID, datumType, bsonObject) - Expect(err).To(BeNil()) - Expect(apply).ToNot(BeNil()) - Expect(revert).ToNot(BeNil()) - - applySet := apply[0]["$set"] - revertUnset := revert[0]["$unset"] - revertSet := revert[1]["$set"] + applySet, _, revertUnset, revertSet := setup(getBSONData(test.PumpSettingsCarelink)) Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "NC17pw1UAaab50iChhQXJ+N9dTi6GduTy9UjsMHolow="})) Expect(applySet).Should(HaveKeyWithValue("bgTarget.0.target", 5.55075)) From c5b5ddc4c15f703d7ff1a07c679fa7f7d0018771 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 29 Feb 2024 13:18:48 +1300 Subject: [PATCH 246/413] fix empty payload issue --- .../utils/migrationUtil.go | 2 +- .../20231128_jellyfish_migration/utils/test/data.go | 10 ++++++++++ migrations/20231128_jellyfish_migration/utils/utils.go | 6 ++---- .../20231128_jellyfish_migration/utils/utils_test.go | 6 ++++++ 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index ef171c9efe..41435f66f0 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -167,7 +167,7 @@ func (d UpdateData) getMongoUpdates() []mongo.WriteModel { } updateOp := mongo.NewUpdateOneModel() updateOp.Filter = d.Filter - updateOp.SetUpdate(bson.M{"$set": bson.M{"_jellyfishValues": d.Revert}}) + updateOp.SetUpdate(bson.M{"$set": bson.M{"_revertUpdates": d.Revert}}) updates = append(updates, updateOp) return updates } diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go index d40badb519..188efbc896 100644 --- a/migrations/20231128_jellyfish_migration/utils/test/data.go +++ b/migrations/20231128_jellyfish_migration/utils/test/data.go @@ -277,6 +277,15 @@ func cgmSettingsDatum() map[string]interface{} { return datum } +func emptyPayload() map[string]interface{} { + datum := base("Dex-device") + datum["payload"] = map[string]interface{}{} + datum["type"] = "cbg" + datum["units"] = "mmol/L" + datum["value"] = 8.1596 + return datum +} + var CBGDexcomG5MobDatum = dexG5MobDatum() var PumpSettingsTandem = tandemPumpSettingsDatum() var PumpSettingsCarelink = carelinkPumpSettings() @@ -286,3 +295,4 @@ var AutomatedBasalTandem = tandemAutomatedBasalDatum() var WizardTandem = tandemWizardDatum() var ReservoirChange = reservoirChangeDeviceEventDatum() var CGMSetting = cgmSettingsDatum() +var EmptyPayloadDatum = emptyPayload() diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 8af9fdcbac..60b07a66e9 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -221,13 +221,11 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s } if payload := updatedObject["payload"]; payload != nil { - - if m, ok := payload.(bson.M); ok { + if m, ok := payload.(map[string]interface{}); ok { if length := len(m); length == 0 { delete(updatedObject, "payload") } } - if strPayload, ok := payload.(string); ok { var payloadMetadata metadata.Metadata err := json.Unmarshal(json.RawMessage(strPayload), &payloadMetadata) @@ -387,7 +385,7 @@ func (b *builder) datumChanges(storedObj map[string]interface{}) ([]bson.M, []bs applyUnset := bson.M{} revertUnset := bson.M{} - for _, change := range changelog.FilterOut([]string{"payload"}) { + for _, change := range changelog { switch change.Type { case diff.CREATE: applySet[strings.Join(change.Path, ".")] = change.To diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 02b09cd419..5ecedd1f00 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -96,6 +96,12 @@ var _ = Describe("back-37", func() { Expect(revertSet).Should(HaveKeyWithValue("units.bg", "mg/dL")) }) + It("will remove empty payload", func() { + _, applyUnset, _, revertSet := setup(getBSONData(test.EmptyPayloadDatum)) + Expect(applyUnset).Should(HaveKeyWithValue("payload", "")) + Expect(revertSet).Should(HaveKeyWithValue("payload", map[string]interface{}{})) + }) + }) }) }) From 06b4f6d62399d7aa8f204a9ae68b7123aa0e84b8 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 29 Feb 2024 14:29:22 +1300 Subject: [PATCH 247/413] test pumpSettings with bolus --- .../utils/test/data.go | 17 +++++++++++++++++ .../utils/utils_test.go | 9 +++++++++ 2 files changed, 26 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go index 188efbc896..e40d50e5cd 100644 --- a/migrations/20231128_jellyfish_migration/utils/test/data.go +++ b/migrations/20231128_jellyfish_migration/utils/test/data.go @@ -1,5 +1,10 @@ package test +import ( + "github.com/tidepool-org/platform/data/types/settings/pump" + pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" +) + func base(deviceID string) map[string]interface{} { return map[string]interface{}{ "_id": "17dbokav5t6pssjv72gm0nie3u25b54m", @@ -286,6 +291,17 @@ func emptyPayload() map[string]interface{} { return datum } +func pumpSettingsWithBolus() map[string]interface{} { + datum := tandemPumpSettingsDatum() + + datum["bolus"] = &pump.BolusMap{ + "bolus-1": pumpTest.NewRandomBolus(), + "bolus-2": pumpTest.NewRandomBolus(), + } + + return datum +} + var CBGDexcomG5MobDatum = dexG5MobDatum() var PumpSettingsTandem = tandemPumpSettingsDatum() var PumpSettingsCarelink = carelinkPumpSettings() @@ -296,3 +312,4 @@ var WizardTandem = tandemWizardDatum() var ReservoirChange = reservoirChangeDeviceEventDatum() var CGMSetting = cgmSettingsDatum() var EmptyPayloadDatum = emptyPayload() +var PumpSettingsWithBolusDatum = pumpSettingsWithBolus() diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 5ecedd1f00..bce32d260c 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -102,6 +102,15 @@ var _ = Describe("back-37", func() { Expect(revertSet).Should(HaveKeyWithValue("payload", map[string]interface{}{})) }) + It("will move misnamed bolus to boluses for pump setting", func() { + bsonObj := getBSONData(test.PumpSettingsWithBolusDatum) + applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) + Expect(applyUnset).Should(HaveKeyWithValue("bolus", "")) + Expect(applySet).Should(HaveKey("boluses")) + Expect(revertSet).Should(HaveKey("bolus")) + Expect(revertUnset).Should(HaveKeyWithValue("boluses", "")) + }) + }) }) }) From e4b380675b3376d4ce9603534dfa7cda460f887b Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 29 Feb 2024 17:44:22 +1300 Subject: [PATCH 248/413] fix so wizard bolus is validated --- migrations/20231128_jellyfish_migration/utils/utils.go | 10 ++++++++-- .../20231128_jellyfish_migration/utils/utils_test.go | 10 ++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 60b07a66e9..9b36b280e4 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -195,9 +195,10 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s } if bolus := updatedObject["bolus"]; bolus != nil { - // NOTE: we are doing this to ensure that the `bolus` is just a string reference - if _, ok := bolus.(string); ok { + // NOTE: we are doing this to ensure that the `bolus` is a valid id reference + if bolusID, ok := bolus.(string); ok { delete(updatedObject, "bolus") + updatedObject["bolusId"] = bolusID } } if bgTargetObj, ok := updatedObject["bgTarget"].(map[string]interface{}); ok { @@ -348,6 +349,11 @@ func (b *builder) datumChanges(storedObj map[string]interface{}) ([]bson.M, []bs return nil, nil, err } + if b.datumType == calculator.Type { + //we have validated the id but don't want to trigger an update + delete(storedObj, "bolus") + } + if deduplicator := datumObject["deduplicator"]; deduplicator != nil { datumObject["_deduplicator"] = deduplicator } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index bce32d260c..0b02b55684 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -111,6 +111,16 @@ var _ = Describe("back-37", func() { Expect(revertUnset).Should(HaveKeyWithValue("boluses", "")) }) + It("wizard datum will not have bolus link removed", func() { + bsonObj := getBSONData(test.WizardTandem) + Expect(bsonObj).Should(HaveKeyWithValue("bolus", "g2h6nohp5sdndpvl2l8kdete00lle4gt")) + applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) + Expect(applyUnset).ShouldNot(HaveKeyWithValue("bolus", "")) + Expect(applySet).ShouldNot(HaveKey("bolusId")) + Expect(revertSet).ShouldNot(HaveKey("bolus")) + Expect(revertUnset).ShouldNot(HaveKey("bolusId")) + }) + }) }) }) From 8e8c99ac31fa91bbd92775c2055e6e197f4a2630 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 5 Mar 2024 12:02:44 +1300 Subject: [PATCH 249/413] updates and tests for payload and annotations --- .../utils/migrationUtil.go | 2 +- .../utils/test/data.go | 17 +++++++++++++---- .../utils/utils.go | 12 ++++++------ .../utils/utils_test.go | 18 ++++++++++++++++++ 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 41435f66f0..2461f2bbdd 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -167,7 +167,7 @@ func (d UpdateData) getMongoUpdates() []mongo.WriteModel { } updateOp := mongo.NewUpdateOneModel() updateOp.Filter = d.Filter - updateOp.SetUpdate(bson.M{"$set": bson.M{"_revertUpdates": d.Revert}}) + updateOp.SetUpdate(bson.M{"$set": bson.M{"_rollbackJellyfishMigration": d.Revert}}) updates = append(updates, updateOp) return updates } diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go index e40d50e5cd..452cda4b57 100644 --- a/migrations/20231128_jellyfish_migration/utils/test/data.go +++ b/migrations/20231128_jellyfish_migration/utils/test/data.go @@ -22,10 +22,9 @@ func base(deviceID string) map[string]interface{} { } } -// annotations and payload as a string rather than object or array -func dexG5MobDatum() map[string]interface{} { +// payload as a string rather than object or array +func dexG5MobDatumStringPayload() map[string]interface{} { datum := base("DexG5Mob_iPhone") - datum["annotations"] = `[{"code":"bg/out-of-range","threshold":40,"value":"low"}]` datum["payload"] = `{"systemTime":"2017-11-05T18:56:51Z","transmitterId":"410X6M","transmitterTicks":5796922,"trend":"flat","trendRate":0.6,"trendRateUnits":"mg/dL/min"}` datum["type"] = "cbg" datum["units"] = "mmol/L" @@ -33,6 +32,15 @@ func dexG5MobDatum() map[string]interface{} { return datum } +func dexG5MobDatumStringAnnotations() map[string]interface{} { + datum := base("DexG5Mob_iPhone") + datum["annotations"] = `[{"code":"bg/out-of-range","threshold":40,"value":"low"}]` + datum["type"] = "cbg" + datum["units"] = "mmol/L" + datum["value"] = 8.1596 + return datum +} + func tandemPumpSettingsDatum() map[string]interface{} { datum := base("tandem99999999") @@ -302,7 +310,8 @@ func pumpSettingsWithBolus() map[string]interface{} { return datum } -var CBGDexcomG5MobDatum = dexG5MobDatum() +var CBGDexcomG5StringPayloadDatum = dexG5MobDatumStringPayload() +var CBGDexcomG5StringAnnotationsDatum = dexG5MobDatumStringAnnotations() var PumpSettingsTandem = tandemPumpSettingsDatum() var PumpSettingsCarelink = carelinkPumpSettings() var PumpSettingsOmnipod = omnipodPumpSettingsDatum() diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 9b36b280e4..0db3a98e5b 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -29,7 +29,6 @@ import ( "github.com/tidepool-org/platform/data/types/settings/cgm" "github.com/tidepool-org/platform/data/types/settings/pump" errorsP "github.com/tidepool-org/platform/errors" - "github.com/tidepool-org/platform/metadata" "github.com/tidepool-org/platform/pointer" structureParser "github.com/tidepool-org/platform/structure/parser" structureValidator "github.com/tidepool-org/platform/structure/validator" @@ -222,28 +221,29 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s } if payload := updatedObject["payload"]; payload != nil { + if m, ok := payload.(map[string]interface{}); ok { if length := len(m); length == 0 { delete(updatedObject, "payload") } } if strPayload, ok := payload.(string); ok { - var payloadMetadata metadata.Metadata + var payloadMetadata map[string]interface{} err := json.Unmarshal(json.RawMessage(strPayload), &payloadMetadata) if err != nil { return nil, errorsP.Newf("payload could not be set from %s", strPayload) } - updatedObject["payload"] = &payloadMetadata + updatedObject["payload"] = payloadMetadata } } if annotations := updatedObject["annotations"]; annotations != nil { if strAnnotations, ok := annotations.(string); ok { - var metadataArray metadata.MetadataArray + var metadataArray []interface{} if err := json.Unmarshal(json.RawMessage(strAnnotations), &metadataArray); err != nil { return nil, errorsP.Newf("annotations could not be set from %s", strAnnotations) } - updatedObject["annotations"] = &metadataArray + updatedObject["annotations"] = metadataArray } } return updatedObject, nil @@ -381,7 +381,7 @@ func (b *builder) datumChanges(storedObj map[string]interface{}) ([]bson.M, []bs delete(datumObject, key) } - changelog, err := diff.Diff(storedObj, datumObject, diff.StructMapKeySupport()) + changelog, err := diff.Diff(storedObj, datumObject, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true)) if err != nil { return nil, nil, err } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 0b02b55684..bd7ce20d92 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -121,6 +121,24 @@ var _ = Describe("back-37", func() { Expect(revertUnset).ShouldNot(HaveKey("bolusId")) }) + It("will convert payload that is stored as a string", func() { + bsonObj := getBSONData(test.CBGDexcomG5StringPayloadDatum) + applySet, _, _, revertSet := setup(bsonObj) + Expect(applySet).Should(HaveKeyWithValue("payload", map[string]interface{}{"systemTime": "2017-11-05T18:56:51Z", "transmitterId": "410X6M", "transmitterTicks": 5.796922e+06, "trend": "flat", "trendRate": 0.6, "trendRateUnits": "mg/dL/min"})) + Expect(revertSet).Should(HaveKeyWithValue("payload", "{\"systemTime\":\"2017-11-05T18:56:51Z\",\"transmitterId\":\"410X6M\",\"transmitterTicks\":5796922,\"trend\":\"flat\",\"trendRate\":0.6,\"trendRateUnits\":\"mg/dL/min\"}")) + }) + + It("will convert annotations that are stored as a string", func() { + bsonObj := getBSONData(test.CBGDexcomG5StringAnnotationsDatum) + applySet, _, _, revertSet := setup(bsonObj) + // annotationsVal := []map[string]interface{}{ + // {"code": "bg/out-of-range", "threshold": 40, "value": "low"}, + // } + // TODO test the actual value + Expect(applySet).Should(HaveKey("annotations")) + Expect(revertSet).Should(HaveKeyWithValue("annotations", "[{\"code\":\"bg/out-of-range\",\"threshold\":40,\"value\":\"low\"}]")) + }) + }) }) }) From 130f4b24eff781d0a15b5706106d0086c69ae761 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 5 Mar 2024 12:47:30 +1300 Subject: [PATCH 250/413] update for deviceEvent with status --- .../20231128_jellyfish_migration/utils/test/data.go | 2 +- migrations/20231128_jellyfish_migration/utils/utils.go | 4 ++++ .../20231128_jellyfish_migration/utils/utils_test.go | 10 ++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go index 452cda4b57..1452243fbe 100644 --- a/migrations/20231128_jellyfish_migration/utils/test/data.go +++ b/migrations/20231128_jellyfish_migration/utils/test/data.go @@ -318,7 +318,7 @@ var PumpSettingsOmnipod = omnipodPumpSettingsDatum() var PumpSettingsOmnipodBGTargetCorrect = omnipodPumpSettingsDatumTargetSet() var AutomatedBasalTandem = tandemAutomatedBasalDatum() var WizardTandem = tandemWizardDatum() -var ReservoirChange = reservoirChangeDeviceEventDatum() +var ReservoirChangeWithStatus = reservoirChangeDeviceEventDatum() var CGMSetting = cgmSettingsDatum() var EmptyPayloadDatum = emptyPayload() var PumpSettingsWithBolusDatum = pumpSettingsWithBolus() diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 0db3a98e5b..90a4040ccc 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -353,6 +353,10 @@ func (b *builder) datumChanges(storedObj map[string]interface{}) ([]bson.M, []bs //we have validated the id but don't want to trigger an update delete(storedObj, "bolus") } + if b.datumType == device.Type { + //we have validated the id but don't want to trigger an update + delete(storedObj, "status") + } if deduplicator := datumObject["deduplicator"]; deduplicator != nil { datumObject["_deduplicator"] = deduplicator diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index bd7ce20d92..ff69f97ba5 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -121,6 +121,16 @@ var _ = Describe("back-37", func() { Expect(revertUnset).ShouldNot(HaveKey("bolusId")) }) + It("device event datum will not have status link removed", func() { + bsonObj := getBSONData(test.ReservoirChangeWithStatus) + Expect(bsonObj).Should(HaveKeyWithValue("status", "cvv61jde62b6i28bgot57f18bor5au1n")) + applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) + Expect(applyUnset).ShouldNot(HaveKeyWithValue("status", "")) + Expect(applySet).ShouldNot(HaveKey("statusId")) + Expect(revertSet).ShouldNot(HaveKey("status")) + Expect(revertUnset).ShouldNot(HaveKey("statusId")) + }) + It("will convert payload that is stored as a string", func() { bsonObj := getBSONData(test.CBGDexcomG5StringPayloadDatum) applySet, _, _, revertSet := setup(bsonObj) From a993085b4f577eb3545b4e482d38865ba0b005a2 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 5 Mar 2024 12:52:08 +1300 Subject: [PATCH 251/413] test debug --- migrations/20231128_jellyfish_migration/utils/utils.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 90a4040ccc..b96e5821c9 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -114,6 +114,9 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s delete(updatedObject, "bolus") } if schedules := updatedObject["sleepSchedules"]; schedules != nil { + + log.Printf("## TODO test for [%s] sleepSchedules %#v", b.datumType, schedules) + // NOTE: this is to fix sleepSchedules so they are in the required map format scheduleNames := map[int]string{0: "1", 1: "2"} sleepScheduleMap := pump.SleepScheduleMap{} From ad5bb2474f10460fc4f970f43d35af45b95aab63 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 5 Mar 2024 14:08:23 +1300 Subject: [PATCH 252/413] status deviceEvent test --- .../20231128_jellyfish_migration/utils/test/data.go | 13 +++++++++++++ .../20231128_jellyfish_migration/utils/utils.go | 6 +++++- .../utils/utils_test.go | 8 ++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go index 1452243fbe..555d3ed8c6 100644 --- a/migrations/20231128_jellyfish_migration/utils/test/data.go +++ b/migrations/20231128_jellyfish_migration/utils/test/data.go @@ -255,6 +255,18 @@ func reservoirChangeDeviceEventDatum() map[string]interface{} { return datum } +func alarmDeviceEventDatum() map[string]interface{} { + datum := base("tandemCIQ100000000000") + datum["type"] = "deviceEvent" + datum["subType"] = "status" + datum["status"] = "suspended" + datum["reason"] = map[string]interface{}{ + "suspended": "automatic", + "resumed": "automatic", + } + return datum +} + func cgmSettingsDatum() map[string]interface{} { datum := base("DexG5MobRec-1111111111111") datum["type"] = "cgmSettings" @@ -319,6 +331,7 @@ var PumpSettingsOmnipodBGTargetCorrect = omnipodPumpSettingsDatumTargetSet() var AutomatedBasalTandem = tandemAutomatedBasalDatum() var WizardTandem = tandemWizardDatum() var ReservoirChangeWithStatus = reservoirChangeDeviceEventDatum() +var AlarmDeviceEventDatum = alarmDeviceEventDatum() var CGMSetting = cgmSettingsDatum() var EmptyPayloadDatum = emptyPayload() var PumpSettingsWithBolusDatum = pumpSettingsWithBolus() diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index b96e5821c9..944d61a6c6 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -358,7 +358,11 @@ func (b *builder) datumChanges(storedObj map[string]interface{}) ([]bson.M, []bs } if b.datumType == device.Type { //we have validated the id but don't want to trigger an update - delete(storedObj, "status") + subType := fmt.Sprintf("%v", storedObj["subType"]) + switch subType { + case reservoirchange.SubType, alarm.SubType: + delete(storedObj, "status") + } } if deduplicator := datumObject["deduplicator"]; deduplicator != nil { diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index ff69f97ba5..e3a6de4077 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -131,6 +131,14 @@ var _ = Describe("back-37", func() { Expect(revertUnset).ShouldNot(HaveKey("statusId")) }) + It("status device event datum with suspended status as suspended will not update it", func() { + bsonObj := getBSONData(test.AlarmDeviceEventDatum) + Expect(bsonObj).Should(HaveKeyWithValue("status", "suspended")) + applySet, _, _, revertSet := setup(bsonObj) + Expect(applySet).ShouldNot(HaveKey("status")) + Expect(revertSet).ShouldNot(HaveKey("status")) + }) + It("will convert payload that is stored as a string", func() { bsonObj := getBSONData(test.CBGDexcomG5StringPayloadDatum) applySet, _, _, revertSet := setup(bsonObj) From bc7fff8deae62e88f80354fe7413689313e8e853 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 5 Mar 2024 17:23:23 +1300 Subject: [PATCH 253/413] start of SleepSchedule test --- .../utils/test/data.go | 63 +++++++++++++++++++ .../utils/utils.go | 14 ++--- .../utils/utils_test.go | 44 ++++++++++++- 3 files changed, 113 insertions(+), 8 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go index 555d3ed8c6..a40d63a397 100644 --- a/migrations/20231128_jellyfish_migration/utils/test/data.go +++ b/migrations/20231128_jellyfish_migration/utils/test/data.go @@ -96,6 +96,68 @@ func tandemPumpSettingsDatum() map[string]interface{} { return datum } +func tandemPumpSettingsWithSleepScheduleDatum() map[string]interface{} { + datum := base("tandem99999999") + + datum["type"] = "pumpSettings" + datum["activeSchedule"] = "Simple" + datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mg/dL"} + datum["basalSchedules"] = map[string]interface{}{ + "Simple": []map[string]interface{}{ + {"rate": 0.5, "start": 0}, + {"rate": 1.35, "start": 55800000}, + }, + "Standard": []map[string]interface{}{ + {"rate": 0.5, "start": 0}, + {"rate": 1.35, "start": 55800000}, + }, + } + datum["carbRatios"] = map[string]interface{}{ + "Simple": []map[string]interface{}{ + {"amount": 10, "start": 0}, + {"amount": 10, "start": 46800000}, + }, + "Standard": []map[string]interface{}{ + {"amount": 10, "start": 0}, + {"amount": 10, "start": 46800000}, + }, + } + datum["insulinSensitivities"] = map[string]interface{}{ + "Simple": []map[string]interface{}{ + {"amount": 2.7753739955227665, "start": 0}, + {"amount": 2.7753739955227665, "start": 46800000}, + }, + "Standard": []map[string]interface{}{ + {"amount": 2.7753739955227665, "start": 0}, + {"amount": 2.7753739955227665, "start": 46800000}, + }, + } + + datum["bgTargets"] = map[string]interface{}{ + "Simple": []map[string]interface{}{ + {"target": 5.550747991045533, "start": 0}, + {"target": 5.550747991045533, "start": 46800000}, + }, + "Standard": []map[string]interface{}{ + {"target": 5.550747991045533, "start": 0}, + {"target": 5.550747991045533, "start": 46800000}, + }, + } + + datum["payload"] = map[string]interface{}{ + "logIndices": []interface{}{0}, + } + + //## TODO test for [pumpSettings] sleepSchedules []interface {}{map[string]interface {}{"days":[]interface {}{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}, "enabled":true, "end":25200, "start":82800}, map[string]interface {}{"days":[]interface {}{"Sunday"}, "enabled":false, "end":32400, "start":3600}} + + datum["sleepSchedules"] = []interface{}{ + map[string]interface{}{"days": []interface{}{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}, "enabled": true, "end": 25200, "start": 82800}, + map[string]interface{}{"days": []interface{}{"Sunday"}, "enabled": false, "end": 32400, "start": 3600}, + } + + return datum +} + func carelinkPumpSettings() map[string]interface{} { datum := base("MiniMed 530G - 751-=-11111111") @@ -325,6 +387,7 @@ func pumpSettingsWithBolus() map[string]interface{} { var CBGDexcomG5StringPayloadDatum = dexG5MobDatumStringPayload() var CBGDexcomG5StringAnnotationsDatum = dexG5MobDatumStringAnnotations() var PumpSettingsTandem = tandemPumpSettingsDatum() +var PumpSettingsWithSleepScheduleTandem = tandemPumpSettingsWithSleepScheduleDatum() var PumpSettingsCarelink = carelinkPumpSettings() var PumpSettingsOmnipod = omnipodPumpSettingsDatum() var PumpSettingsOmnipodBGTargetCorrect = omnipodPumpSettingsDatumTargetSet() diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 944d61a6c6..0d889a8f18 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -119,26 +119,26 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s // NOTE: this is to fix sleepSchedules so they are in the required map format scheduleNames := map[int]string{0: "1", 1: "2"} - sleepScheduleMap := pump.SleepScheduleMap{} + sleepScheduleMap := map[string]interface{}{} dataBytes, err := json.Marshal(schedules) if err != nil { return nil, err } - schedulesArray := []*pump.SleepSchedule{} + schedulesArray := []map[string]interface{}{} err = json.Unmarshal(dataBytes, &schedulesArray) if err != nil { return nil, err } for i, schedule := range schedulesArray { - days := schedule.Days + days := schedule["days"].([]interface{}) updatedDays := []string{} - for _, day := range *days { - if !slices.Contains(common.DaysOfWeek(), strings.ToLower(day)) { + for _, day := range days { + if !slices.Contains(common.DaysOfWeek(), strings.ToLower(fmt.Sprintf("%v", day))) { return nil, errorsP.Newf("pumpSettings.sleepSchedules has an invalid day of week %s", day) } - updatedDays = append(updatedDays, strings.ToLower(day)) + updatedDays = append(updatedDays, strings.ToLower(fmt.Sprintf("%v", day))) } - schedule.Days = &updatedDays + schedule["days"] = updatedDays sleepScheduleMap[scheduleNames[i]] = schedule } updatedObject["sleepSchedules"] = sleepScheduleMap diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index e3a6de4077..e6eb6074fb 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -68,6 +68,49 @@ var _ = Describe("back-37", func() { Expect(revertSet).Should(HaveKeyWithValue("units.bg", "mg/dL")) }) + It("pump settings with sleep schedule updates", func() { + + applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.PumpSettingsWithSleepScheduleTandem)) + + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "bpKLJbi5JfqD7N0WJ1vj0ck03c9EZ3U0H09TCLhdd3k="})) + Expect(applySet).Should(HaveKey("sleepSchedules")) + + // expectedSchedules := map[string]interface{}{ + // "1": map[string]interface{}{ + // "enabled": true, + // "days": []interface{}{"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"}, + // "start": 82800, + // "end": 25200, + // }, + // "2": map[string]interface{}{ + // "enabled": false, + // "days": []interface{}{"sunday"}, + // "start": 3600, + // "end": 32400, + // }, + // } + + // originalSchedules := []map[string]interface{}{ + // map[string]interface{}{ + // "enabled": true, + // "days": []interface{}{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}, + // "start": 82800, + // "end": 25200, + // }, + // map[string]interface{}{ + // "enabled": false, + // "days": []interface{}{"Sunday"}, + // "start": 3600, + // "end": 32400, + // }, + // } + + Expect(applyUnset).Should(HaveKeyWithValue("localTime", "")) + Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + Expect(revertSet).Should(HaveKey("sleepSchedules")) + + }) + It("wizard with bgInput and bgTarget glucose updates", func() { applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.WizardTandem)) @@ -156,7 +199,6 @@ var _ = Describe("back-37", func() { Expect(applySet).Should(HaveKey("annotations")) Expect(revertSet).Should(HaveKeyWithValue("annotations", "[{\"code\":\"bg/out-of-range\",\"threshold\":40,\"value\":\"low\"}]")) }) - }) }) }) From c23f149486305284aa2d2d601cc1b84a8c3caa3f Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 6 Mar 2024 09:03:03 +1300 Subject: [PATCH 254/413] tests for annotations and sleepSchedules --- .../utils/utils_test.go | 83 +++++++++++-------- 1 file changed, 50 insertions(+), 33 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index e6eb6074fb..7457c39388 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -6,6 +6,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils/test" @@ -75,39 +76,49 @@ var _ = Describe("back-37", func() { Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "bpKLJbi5JfqD7N0WJ1vj0ck03c9EZ3U0H09TCLhdd3k="})) Expect(applySet).Should(HaveKey("sleepSchedules")) - // expectedSchedules := map[string]interface{}{ - // "1": map[string]interface{}{ - // "enabled": true, - // "days": []interface{}{"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"}, - // "start": 82800, - // "end": 25200, - // }, - // "2": map[string]interface{}{ - // "enabled": false, - // "days": []interface{}{"sunday"}, - // "start": 3600, - // "end": 32400, - // }, - // } - - // originalSchedules := []map[string]interface{}{ - // map[string]interface{}{ - // "enabled": true, - // "days": []interface{}{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}, - // "start": 82800, - // "end": 25200, - // }, - // map[string]interface{}{ - // "enabled": false, - // "days": []interface{}{"Sunday"}, - // "start": 3600, - // "end": 32400, - // }, - // } + applyObj := applySet.(primitive.M) + + actualSchedules := applyObj["sleepSchedules"] + + expectedSchedules := map[string]interface{}{ + "1": map[string]interface{}{ + "enabled": true, + "days": []interface{}{"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"}, + "start": 82800, + "end": 25200, + }, + "2": map[string]interface{}{ + "enabled": false, + "days": []interface{}{"sunday"}, + "start": 3600, + "end": 32400, + }, + } + + Expect(fmt.Sprintf("%v", actualSchedules)).To(Equal(fmt.Sprintf("%v", expectedSchedules))) Expect(applyUnset).Should(HaveKeyWithValue("localTime", "")) Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) Expect(revertSet).Should(HaveKey("sleepSchedules")) + revertSetObj := revertSet.(primitive.M) + actualRevrtSchedules := revertSetObj["sleepSchedules"] + + originalSchedules := []map[string]interface{}{ + { + "enabled": true, + "days": []interface{}{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}, + "start": 82800, + "end": 25200, + }, + { + "enabled": false, + "days": []interface{}{"Sunday"}, + "start": 3600, + "end": 32400, + }, + } + + Expect(fmt.Sprintf("%v", actualRevrtSchedules)).To(Equal(fmt.Sprintf("%v", originalSchedules))) }) @@ -192,11 +203,17 @@ var _ = Describe("back-37", func() { It("will convert annotations that are stored as a string", func() { bsonObj := getBSONData(test.CBGDexcomG5StringAnnotationsDatum) applySet, _, _, revertSet := setup(bsonObj) - // annotationsVal := []map[string]interface{}{ - // {"code": "bg/out-of-range", "threshold": 40, "value": "low"}, - // } - // TODO test the actual value + Expect(applySet).Should(HaveKey("annotations")) + + expectedAnnotations := []interface{}{ + map[string]interface{}{"code": "bg/out-of-range", "threshold": 40, "value": "low"}, + } + applyObj := applySet.(primitive.M) + actualAnnotations := applyObj["annotations"] + + Expect(fmt.Sprintf("%v", actualAnnotations)).To(Equal(fmt.Sprintf("%v", expectedAnnotations))) + Expect(revertSet).Should(HaveKeyWithValue("annotations", "[{\"code\":\"bg/out-of-range\",\"threshold\":40,\"value\":\"low\"}]")) }) }) From 9b6e227ec7db2e8605fdcc7d002d6eb18a64202c Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 6 Mar 2024 10:12:56 +1300 Subject: [PATCH 255/413] only write audit log if a dry run --- .../20231128_jellyfish_migration/utils/migrationUtil.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 2461f2bbdd..eb19eb5a4e 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -234,6 +234,12 @@ func (m *migrationUtil) writeErrors(groupLimit *int) { } func (m *migrationUtil) writeAudit(groupLimit *int) { + + if !m.config.dryRun { + m.groupedDiffs = map[string][]UpdateData{} + return + } + for group, diffs := range m.groupedDiffs { if groupLimit != nil { if len(diffs) < *groupLimit { From beecdc5aae789621bcf9ca32c4892b417fbf0198 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 6 Mar 2024 10:15:22 +1300 Subject: [PATCH 256/413] update logging --- migrations/20231128_jellyfish_migration/utils/utils.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 0d889a8f18..297d63e046 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -115,8 +115,6 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s } if schedules := updatedObject["sleepSchedules"]; schedules != nil { - log.Printf("## TODO test for [%s] sleepSchedules %#v", b.datumType, schedules) - // NOTE: this is to fix sleepSchedules so they are in the required map format scheduleNames := map[int]string{0: "1", 1: "2"} sleepScheduleMap := map[string]interface{}{} @@ -164,7 +162,7 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s } } if overridePresets := updatedObject["overridePresets"]; overridePresets != nil { - log.Printf("## TODO [%s] overridePresets %#v", b.datumType, overridePresets) + log.Printf("## TODO [%s] [%s] overridePresets %#v", b.datumType, b.datumID, overridePresets) } case selfmonitored.Type, ketone.Type, continuous.Type: From 5b0b505f2f46d7de00b96031ad41d7bc5b0b2fe9 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 6 Mar 2024 13:46:47 +1300 Subject: [PATCH 257/413] migration updates --- migrations/20231128_jellyfish_migration/jellyfish_audit.sh | 3 +++ .../20231128_jellyfish_migration/jellyfish_migration.sh | 3 +++ .../20231128_jellyfish_migration/utils/migrationUtil.go | 6 ++---- 3 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 migrations/20231128_jellyfish_migration/jellyfish_audit.sh create mode 100644 migrations/20231128_jellyfish_migration/jellyfish_migration.sh diff --git a/migrations/20231128_jellyfish_migration/jellyfish_audit.sh b/migrations/20231128_jellyfish_migration/jellyfish_audit.sh new file mode 100644 index 0000000000..af42d72f12 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/jellyfish_audit.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +go run jellyfish_migration.go --dry-run --cap=500000 --nop-percent=1 --query-limit=100 --query-batch=50 diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.sh b/migrations/20231128_jellyfish_migration/jellyfish_migration.sh new file mode 100644 index 0000000000..8719cffa83 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +go run jellyfish_migration.go --cap=500000 --nop-percent=1 --query-limit=100 --query-batch=50 diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index eb19eb5a4e..7b260ef4d4 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -183,7 +183,6 @@ func (m *migrationUtil) SetLastProcessed(lastID string) { func createFile(fileType string, dataGroup string, logName string) (*os.File, error) { datetime := time.Now().Round(15 * time.Minute) - timestamp := strings.Replace(datetime.Format(time.TimeOnly), ":", "_", -1) datestamp := datetime.Format(time.DateOnly) var err error if fileType == "" { @@ -199,7 +198,7 @@ func createFile(fileType string, dataGroup string, logName string) (*os.File, er return nil, err } logName = fmt.Sprintf(logName, dataGroup) - logPath := filepath.Join(".", fileType, datestamp, timestamp) + logPath := filepath.Join(".", fileType, datestamp) err = os.MkdirAll(logPath, os.ModePerm) if err != nil { @@ -551,7 +550,6 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio } if m.config.dryRun { - //TODO clean this up a bit writtenCount += len(batch) continue } @@ -566,7 +564,7 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio } m.updates = []mongo.WriteModel{} m.updatedCount = m.updatedCount + writtenCount - writeLimit := 500 + writeLimit := 5000 if m.config.dryRun { log.Println("dry-run so no changes applied") m.writeAudit(&writeLimit) From 821637c13171a68fba3cb3cdaf3bfb5e7f6ad84a Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 6 Mar 2024 18:15:53 +1300 Subject: [PATCH 258/413] allow for start of revert changes errors and audit data now json per line --- .../jellyfish_migration.go | 88 ++++++++++++++++++- .../utils/migrationUtil.go | 16 +++- 2 files changed, 99 insertions(+), 5 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index c674beb2c0..4489e23776 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -9,6 +9,7 @@ import ( "github.com/urfave/cli" "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" @@ -28,6 +29,7 @@ type config struct { uri string dryRun bool stopOnErr bool + revertChanges bool userID string lastUpdatedId string nopPercent int @@ -70,7 +72,7 @@ func (m *Migration) RunAndExit() { //TODO: just capping while doing test runs, but probably good to have as a general ability cap := m.config.cap // while testing m.migrationUtil, err = utils.NewMigrationUtil( - utils.NewMigrationUtilConfig(&m.config.dryRun, &m.config.stopOnErr, &m.config.nopPercent, &cap), + utils.NewMigrationUtilConfig(&m.config.dryRun, &m.config.stopOnErr, &m.config.revertChanges, &m.config.nopPercent, &cap), m.client, &m.config.lastUpdatedId, ) @@ -82,6 +84,13 @@ func (m *Migration) RunAndExit() { log.Printf("prepare failed: %s", err) return err } + if m.config.revertChanges { + if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndRevert); err != nil { + log.Printf("revert failed: %s", err) + return err + } + return nil + } if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndProcess); err != nil { log.Printf("processing failed: %s", err) return err @@ -117,6 +126,11 @@ func (m *Migration) Initialize() error { Usage: "stop migration on error", Destination: &m.config.stopOnErr, }, + cli.BoolFlag{ + Name: "revert-changes", + Usage: "revert migration changes that have been applied", + Destination: &m.config.revertChanges, + }, cli.IntFlag{ Name: "cap", Usage: "max number of records migrate", @@ -180,7 +194,9 @@ func (m *Migration) getDataCollection() *mongo.Collection { func (m *Migration) fetchAndProcess() bool { - selector := bson.M{} + selector := bson.M{ + "_deduplicator": bson.M{"$exists": false}, + } if strings.TrimSpace(m.config.userID) != "" { log.Printf("fetching for user %s", m.config.userID) @@ -248,3 +264,71 @@ func (m *Migration) fetchAndProcess() bool { } return false } + +func (m *Migration) fetchAndRevert() bool { + + selector := bson.M{ + "_rollbackJellyfishMigration": bson.M{"$exists": true}, + } + + if strings.TrimSpace(m.config.userID) != "" { + log.Printf("fetching for user %s", m.config.userID) + selector["_userId"] = m.config.userID + } + + // jellyfish uses a generated _id that is not an mongo objectId + idNotObjectID := bson.M{"$not": bson.M{"$type": "objectId"}} + + if lastID := m.migrationUtil.GetLastID(); lastID != "" { + selector["$and"] = []interface{}{ + bson.M{"_id": bson.M{"$gt": lastID}}, + bson.M{"_id": idNotObjectID}, + } + } else { + selector["_id"] = idNotObjectID + } + + batchSize := int32(m.config.queryBatchSize) + + if dataC := m.getDataCollection(); dataC != nil { + + dDataCursor, err := dataC.Find(m.ctx, selector, + &options.FindOptions{ + Sort: bson.M{"_id": 1}, + BatchSize: &batchSize, + Limit: &m.config.queryLimit, + }, + ) + if err != nil { + log.Printf("failed to select data: %s", err) + return false + } + defer dDataCursor.Close(m.ctx) + + all := []bson.M{} + + for dDataCursor.Next(m.ctx) { + item := bson.M{} + if err := dDataCursor.Decode(&item); err != nil { + log.Printf("error decoding data: %s", err) + return false + } + + revertCommands := item["_rollbackJellyfishMigration"].(primitive.M) + itemID := fmt.Sprintf("%v", item["_id"]) + userID := fmt.Sprintf("%v", item["_userId"]) + + if setCmd := revertCommands["$set"]; setCmd != nil { + log.Printf("# TODO %s %s $set %v", itemID, userID, setCmd) + } + + if unsetCmd := revertCommands["$unset"]; unsetCmd != nil { + log.Printf("# TODO %s %s $unset %v", itemID, userID, unsetCmd) + } + + } + m.migrationUtil.SetFetched(all) + return len(all) > 0 + } + return false +} diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 7b260ef4d4..d3f309336f 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -20,6 +20,8 @@ import ( type MigrationUtilConfig struct { //apply no changes dryRun bool + //revert the changes that have been applied + revertChanges bool //halt on error stopOnErr bool minOplogWindow int @@ -226,7 +228,7 @@ func (m *migrationUtil) writeErrors(groupLimit *int) { log.Println(err) os.Exit(1) } - f.WriteString(string(errJSON) + ",\n") + f.WriteString(string(errJSON) + "\n") } m.groupedErrors[group] = []ErrorData{} } @@ -257,7 +259,7 @@ func (m *migrationUtil) writeAudit(groupLimit *int) { log.Println(err) os.Exit(1) } - f.WriteString(string(diffJSON) + ",\n") + f.WriteString(string(diffJSON) + "\n") } m.groupedDiffs[group] = []UpdateData{} } @@ -289,7 +291,7 @@ func (m *migrationUtil) GetLastID() string { return m.lastUpdatedId } -func NewMigrationUtilConfig(dryRun *bool, stopOnErr *bool, nopPercent *int, cap *int) *MigrationUtilConfig { +func NewMigrationUtilConfig(dryRun *bool, stopOnErr *bool, revertChanges *bool, nopPercent *int, cap *int) *MigrationUtilConfig { cfg := &MigrationUtilConfig{ minOplogWindow: 28800, // 8hrs minFreePercent: 10, @@ -305,6 +307,9 @@ func NewMigrationUtilConfig(dryRun *bool, stopOnErr *bool, nopPercent *int, cap if stopOnErr != nil { cfg.SetStopOnErr(*stopOnErr) } + if revertChanges != nil { + cfg.SetRevertChanges(*revertChanges) + } if nopPercent != nil { cfg.SetNopPercent(*nopPercent) } @@ -341,6 +346,11 @@ func (c *MigrationUtilConfig) SetStopOnErr(stopOnErr bool) *MigrationUtilConfig return c } +func (c *MigrationUtilConfig) SetRevertChanges(revertChanges bool) *MigrationUtilConfig { + c.revertChanges = revertChanges + return c +} + // OnError // - write error to file `error.log` in directory cli is running in // - optionally stop the operation if stopOnErr is true in the config From 69af9714b309e80b9bb58b4534634e02d316726e Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 7 Mar 2024 09:01:09 +1300 Subject: [PATCH 259/413] error filtering --- .../search_errors.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 migrations/20231128_jellyfish_migration/search_errors.sh diff --git a/migrations/20231128_jellyfish_migration/search_errors.sh b/migrations/20231128_jellyfish_migration/search_errors.sh new file mode 100644 index 0000000000..0f23103bd2 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/search_errors.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +INPUT_FILE=$1 +OUTPUT_FILE=$2 +EXCLUDE_TXT=$3 +TMP_FILE=tmp.json + +echo "input_file: $INPUT_FILE" +echo "output_file: $OUTPUT_FILE" +echo "exclusion: $EXCLUDE_TXT" + +# move to json array +jq -cnr '(reduce inputs as $line ([]; . + [$line]))' $INPUT_FILE >$TMP_FILE + +# iterate json and filter out known error +jq -c ".[] | select(.error, ._id | .detail | contains($EXCLUDE_TXT) | not ) | {detail: .error.detail, id: ._id}" $TMP_FILE >$OUTPUT_FILE + +rm $TMP_FILE From f067e666b46790013000ceeb91f43980ad51ac8d Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 7 Mar 2024 15:46:13 +1300 Subject: [PATCH 260/413] show percent processed --- .../20231128_jellyfish_migration/search_errors.sh | 12 ++++++------ .../utils/migrationUtil.go | 13 ++++++++++--- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/search_errors.sh b/migrations/20231128_jellyfish_migration/search_errors.sh index 0f23103bd2..011cb6ecaf 100644 --- a/migrations/20231128_jellyfish_migration/search_errors.sh +++ b/migrations/20231128_jellyfish_migration/search_errors.sh @@ -7,12 +7,12 @@ TMP_FILE=tmp.json echo "input_file: $INPUT_FILE" echo "output_file: $OUTPUT_FILE" -echo "exclusion: $EXCLUDE_TXT" +echo "exclude error code: $EXCLUDE_TXT" -# move to json array -jq -cnr '(reduce inputs as $line ([]; . + [$line]))' $INPUT_FILE >$TMP_FILE - -# iterate json and filter out known error -jq -c ".[] | select(.error, ._id | .detail | contains($EXCLUDE_TXT) | not ) | {detail: .error.detail, id: ._id}" $TMP_FILE >$OUTPUT_FILE +if [[ -z "$EXCLUDE_TXT" ]]; then + jq -c "map(.error)|unique_by(.code)|.[]" $TMP_FILE >$OUTPUT_FILE +else + jq -c "map(.error)|unique_by(.code)|.[]|select(.code!=null)|select(.code|contains(\"$EXCLUDE_TXT\")|not)" $TMP_FILE >$OUTPUT_FILE +fi rm $TMP_FILE diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index d3f309336f..5692cdb9dc 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -135,6 +135,11 @@ func (m *migrationUtil) Initialize(ctx context.Context, dataC *mongo.Collection) func (m *migrationUtil) capReached() bool { if m.config.cap != nil { stats := m.GetStats() + + percent := stats.Applied / *m.config.cap + + log.Printf("percent %v processed of %d records", percent, *m.config.cap) // start + if *m.config.cap <= stats.Applied || *m.config.cap <= stats.Fetched { log.Printf("cap [%d] updated [%d] fetched [%d]", *m.config.cap, stats.Applied, stats.Fetched) return true @@ -152,6 +157,7 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe if m.capReached() { break } + } m.GetStats().report() m.writeErrors(nil) @@ -550,7 +556,7 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio return batches } writtenCount := 0 - writeStart := time.Now() + //writeStart := time.Now() for _, batch := range getBatches(int(*m.writeBatchSize)) { if err := m.blockUntilDBReady(ctx); err != nil { return err @@ -579,8 +585,9 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio log.Println("dry-run so no changes applied") m.writeAudit(&writeLimit) } else { - log.Printf("write took [%s] for [%d] items\n", time.Since(writeStart), writtenCount) - m.GetStats().report() + + //log.Printf("write took [%s] for [%d] items\n", time.Since(writeStart), writtenCount) + //m.GetStats().report() m.writeErrors(&writeLimit) m.writeAudit(&writeLimit) } From 2fe84d9a8ee5fa878db8d49cd61d49e1547b0542 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 7 Mar 2024 16:11:45 +1300 Subject: [PATCH 261/413] show percent process --- .../20231128_jellyfish_migration/utils/migrationUtil.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 5692cdb9dc..9c48a4fc89 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -136,9 +136,8 @@ func (m *migrationUtil) capReached() bool { if m.config.cap != nil { stats := m.GetStats() - percent := stats.Applied / *m.config.cap - - log.Printf("percent %v processed of %d records", percent, *m.config.cap) // start + percent := (float64(stats.Applied) * float64(100)) / float64(*m.config.cap) + log.Printf("processed %.1f %% of %d records", percent, *m.config.cap) if *m.config.cap <= stats.Applied || *m.config.cap <= stats.Fetched { log.Printf("cap [%d] updated [%d] fetched [%d]", *m.config.cap, stats.Applied, stats.Fetched) From eb4463967c665dba0a02574fbc30f5348f5a0830 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 8 Mar 2024 07:48:33 +1300 Subject: [PATCH 262/413] cleanup error checking --- migrations/20231128_jellyfish_migration/search_errors.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/search_errors.sh b/migrations/20231128_jellyfish_migration/search_errors.sh index 011cb6ecaf..e4c914f8c7 100644 --- a/migrations/20231128_jellyfish_migration/search_errors.sh +++ b/migrations/20231128_jellyfish_migration/search_errors.sh @@ -9,10 +9,10 @@ echo "input_file: $INPUT_FILE" echo "output_file: $OUTPUT_FILE" echo "exclude error code: $EXCLUDE_TXT" -if [[ -z "$EXCLUDE_TXT" ]]; then +jq -cnr '(reduce inputs as $line ([]; . + [$line]))' $INPUT_FILE >$TMP_FILE + +if [[ -z "$EXCLUDE_TXT" ]]; then jq -c "map(.error)|unique_by(.code)|.[]" $TMP_FILE >$OUTPUT_FILE else jq -c "map(.error)|unique_by(.code)|.[]|select(.code!=null)|select(.code|contains(\"$EXCLUDE_TXT\")|not)" $TMP_FILE >$OUTPUT_FILE fi - -rm $TMP_FILE From 659bc2dc4ddc591ef2eaf040ccd9fc0a241d9a0f Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 12 Mar 2024 11:05:51 +1300 Subject: [PATCH 263/413] query updates for filtering --- migrations/20231128_jellyfish_migration/search_errors.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/search_errors.sh b/migrations/20231128_jellyfish_migration/search_errors.sh index e4c914f8c7..ce41d81966 100644 --- a/migrations/20231128_jellyfish_migration/search_errors.sh +++ b/migrations/20231128_jellyfish_migration/search_errors.sh @@ -12,7 +12,7 @@ echo "exclude error code: $EXCLUDE_TXT" jq -cnr '(reduce inputs as $line ([]; . + [$line]))' $INPUT_FILE >$TMP_FILE if [[ -z "$EXCLUDE_TXT" ]]; then - jq -c "map(.error)|unique_by(.code)|.[]" $TMP_FILE >$OUTPUT_FILE + jq -c "map(.)|unique_by(.error.detail)|.[]|{"id":._id,"detail":.error.detail,"code":.error.code}" $TMP_FILE >$OUTPUT_FILE else - jq -c "map(.error)|unique_by(.code)|.[]|select(.code!=null)|select(.code|contains(\"$EXCLUDE_TXT\")|not)" $TMP_FILE >$OUTPUT_FILE + jq -c "map(.)|unique_by(.error.detail)|.[]|select(.error.detail!=null)|select(.error.detail|contains(\"$EXCLUDE_TXT\")|not)|.[]|{"id":._id,"detail":.error.detail,"code":.error.code}" $TMP_FILE >$OUTPUT_FILE fi From 1fffd0a7d4b7d3a0f95fca7bf3110399be2bbfbf Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 12 Mar 2024 12:06:02 +1300 Subject: [PATCH 264/413] revert of changes --- .../20231128_jellyfish_migration/jellyfish_migration.go | 3 +++ .../revert_jellyfish_migration.sh | 3 +++ .../20231128_jellyfish_migration/utils/migrationUtil.go | 8 ++++---- 3 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 migrations/20231128_jellyfish_migration/revert_jellyfish_migration.sh diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 4489e23776..86295139e8 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -84,6 +84,9 @@ func (m *Migration) RunAndExit() { log.Printf("prepare failed: %s", err) return err } + + log.Printf("migration config: %#v", m.config) + if m.config.revertChanges { if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndRevert); err != nil { log.Printf("revert failed: %s", err) diff --git a/migrations/20231128_jellyfish_migration/revert_jellyfish_migration.sh b/migrations/20231128_jellyfish_migration/revert_jellyfish_migration.sh new file mode 100644 index 0000000000..de2059af8e --- /dev/null +++ b/migrations/20231128_jellyfish_migration/revert_jellyfish_migration.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +go run jellyfish_migration.go --cap=500000 --nop-percent=1 --query-limit=100 --query-batch=50 --revert-changes diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 9c48a4fc89..3234db73a6 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -301,10 +301,10 @@ func NewMigrationUtilConfig(dryRun *bool, stopOnErr *bool, revertChanges *bool, minOplogWindow: 28800, // 8hrs minFreePercent: 10, expectedOplogEntrySize: 420, - - dryRun: true, - stopOnErr: true, - nopPercent: 25, + revertChanges: true, + dryRun: true, + stopOnErr: true, + nopPercent: 25, } if dryRun != nil { cfg.SetDryRun(*dryRun) From 8855e7ea6f84a91e9a7872d55a747ac257f6968d Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 12 Mar 2024 13:20:49 +1300 Subject: [PATCH 265/413] general writeLastProcessed for audit, process and revert --- .../jellyfish_migration.go | 21 +++++++------------ .../utils/migrationUtil.go | 15 +++---------- 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 86295139e8..ecc059c00b 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -69,8 +69,7 @@ func (m *Migration) RunAndExit() { return fmt.Errorf("unable to connect to MongoDB: %w", err) } defer m.client.Disconnect(m.ctx) - //TODO: just capping while doing test runs, but probably good to have as a general ability - cap := m.config.cap // while testing + cap := m.config.cap m.migrationUtil, err = utils.NewMigrationUtil( utils.NewMigrationUtilConfig(&m.config.dryRun, &m.config.stopOnErr, &m.config.revertChanges, &m.config.nopPercent, &cap), m.client, @@ -160,8 +159,8 @@ func (m *Migration) Initialize() error { Usage: "id of last datum updated", Destination: &m.config.lastUpdatedId, Required: false, - //id of last datum updated read and written to file `lastUpdatedId` - FilePath: "./lastUpdatedId", + //id of last datum updated read and written to file `lastProcessedId` + FilePath: "./lastProcessedId", }, cli.StringFlag{ Name: "user-id", @@ -317,18 +316,14 @@ func (m *Migration) fetchAndRevert() bool { return false } - revertCommands := item["_rollbackJellyfishMigration"].(primitive.M) + rollbackCmds := item["_rollbackJellyfishMigration"].(primitive.A) itemID := fmt.Sprintf("%v", item["_id"]) userID := fmt.Sprintf("%v", item["_userId"]) - - if setCmd := revertCommands["$set"]; setCmd != nil { - log.Printf("# TODO %s %s $set %v", itemID, userID, setCmd) - } - - if unsetCmd := revertCommands["$unset"]; unsetCmd != nil { - log.Printf("# TODO %s %s $unset %v", itemID, userID, unsetCmd) + for _, cmd := range rollbackCmds { + log.Printf("# TODO %s %s apply command %v", itemID, userID, cmd) } - + log.Printf("# TODO delete %s _rollbackJellyfishMigration now reverts applied", itemID) + m.migrationUtil.SetLastProcessed(itemID) } m.migrationUtil.SetFetched(all) return len(all) > 0 diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 3234db73a6..4a1e07a7a4 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -378,14 +378,9 @@ func (m *migrationUtil) getAdminDB() *mongo.Database { return m.client.Database("admin") } -func writeLastItemUpdate(itemID string, dryRun bool) { +func writeLastProcessed(itemID string) { if strings.TrimSpace(itemID) != "" { - //TODO - i think we still want this so we can keep processing in order - if dryRun { - log.Printf("dry run so not setting lastUpdatedId %s", itemID) - return - } - f, err := os.Create("./lastUpdatedId") + f, err := os.Create("./lastProcessedId") if err != nil { log.Println(err) os.Exit(1) @@ -555,7 +550,6 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio return batches } writtenCount := 0 - //writeStart := time.Now() for _, batch := range getBatches(int(*m.writeBatchSize)) { if err := m.blockUntilDBReady(ctx); err != nil { return err @@ -575,7 +569,7 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio } writtenCount += int(results.ModifiedCount) - writeLastItemUpdate(m.lastUpdatedId, m.config.dryRun) + writeLastProcessed(m.lastUpdatedId) } m.updates = []mongo.WriteModel{} m.updatedCount = m.updatedCount + writtenCount @@ -584,9 +578,6 @@ func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collectio log.Println("dry-run so no changes applied") m.writeAudit(&writeLimit) } else { - - //log.Printf("write took [%s] for [%d] items\n", time.Since(writeStart), writtenCount) - //m.GetStats().report() m.writeErrors(&writeLimit) m.writeAudit(&writeLimit) } From 0d0ea1d9b4da490dc1cf87fad9e1bed2b99971b7 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 12 Mar 2024 14:35:22 +1300 Subject: [PATCH 266/413] updates for apply rollback --- .../jellyfish_migration.go | 20 +++++++------- .../utils/migrationUtil.go | 27 +++++++++++-------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index ecc059c00b..6841ef4bb7 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -84,8 +84,6 @@ func (m *Migration) RunAndExit() { return err } - log.Printf("migration config: %#v", m.config) - if m.config.revertChanges { if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndRevert); err != nil { log.Printf("revert failed: %s", err) @@ -256,7 +254,7 @@ func (m *Migration) fetchAndProcess() bool { ItemType: itemType, Apply: updates, Revert: revert, - }) + }, false) } m.migrationUtil.SetLastProcessed(itemID) all = append(all, item) @@ -315,14 +313,18 @@ func (m *Migration) fetchAndRevert() bool { log.Printf("error decoding data: %s", err) return false } - - rollbackCmds := item["_rollbackJellyfishMigration"].(primitive.A) + rollbackCmds := item["_rollbackJellyfishMigration"].([]primitive.M) itemID := fmt.Sprintf("%v", item["_id"]) userID := fmt.Sprintf("%v", item["_userId"]) - for _, cmd := range rollbackCmds { - log.Printf("# TODO %s %s apply command %v", itemID, userID, cmd) - } - log.Printf("# TODO delete %s _rollbackJellyfishMigration now reverts applied", itemID) + itemType := fmt.Sprintf("%v", item["type"]) + + m.migrationUtil.SetUpdates(utils.UpdateData{ + Filter: bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}, + ItemID: itemID, + UserID: userID, + ItemType: itemType, + Apply: rollbackCmds, + }, true) m.migrationUtil.SetLastProcessed(itemID) } m.migrationUtil.SetFetched(all) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 4a1e07a7a4..fe218c4bbb 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -54,12 +54,13 @@ type migrationUtil struct { } type UpdateData struct { - Filter interface{} `json:"-"` - ItemID string `json:"_id"` - UserID string `json:"_userId"` - ItemType string `json:"-"` - Apply []bson.M `json:"apply"` - Revert []bson.M `json:"revert"` + Filter interface{} `json:"-"` + ItemID string `json:"_id"` + UserID string `json:"_userId"` + ItemType string `json:"-"` + Apply []bson.M `json:"apply"` + ApplyLast bson.M `json:"applyLast"` + Revert []bson.M `json:"revert"` } type ErrorData struct { @@ -83,7 +84,7 @@ type MigrationUtil interface { Initialize(ctx context.Context, dataC *mongo.Collection) error Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func() bool) error OnError(data ErrorData) - SetUpdates(data UpdateData) + SetUpdates(data UpdateData, asRollback bool) SetLastProcessed(lastID string) SetFetched(raw []bson.M) GetLastID() string @@ -164,7 +165,7 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe return nil } -func (d UpdateData) getMongoUpdates() []mongo.WriteModel { +func (d UpdateData) getDatumUpdates(asRollback bool) []mongo.WriteModel { updates := []mongo.WriteModel{} for _, u := range d.Apply { updateOp := mongo.NewUpdateOneModel() @@ -174,14 +175,18 @@ func (d UpdateData) getMongoUpdates() []mongo.WriteModel { } updateOp := mongo.NewUpdateOneModel() updateOp.Filter = d.Filter - updateOp.SetUpdate(bson.M{"$set": bson.M{"_rollbackJellyfishMigration": d.Revert}}) + if !asRollback && len(d.Revert) > 0 { + updateOp.SetUpdate(bson.M{"$set": bson.M{"_rollbackJellyfishMigration": d.Revert}}) + } else if asRollback { + updateOp.SetUpdate(bson.M{"$unset": bson.M{"_rollbackJellyfishMigration": ""}}) + } updates = append(updates, updateOp) return updates } -func (m *migrationUtil) SetUpdates(data UpdateData) { +func (m *migrationUtil) SetUpdates(data UpdateData, asRollback bool) { m.groupedDiffs[data.ItemType] = append(m.groupedDiffs[data.ItemType], data) - m.updates = append(m.updates, data.getMongoUpdates()...) + m.updates = append(m.updates, data.getDatumUpdates(asRollback)...) } func (m *migrationUtil) SetLastProcessed(lastID string) { From b8f45f54431d10371d351a3194524c0eaf7804a2 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 12 Mar 2024 15:23:24 +1300 Subject: [PATCH 267/413] rollback cmds --- .../jellyfish_migration.go | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 6841ef4bb7..a9df6f37b8 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -313,18 +313,28 @@ func (m *Migration) fetchAndRevert() bool { log.Printf("error decoding data: %s", err) return false } - rollbackCmds := item["_rollbackJellyfishMigration"].([]primitive.M) + cmds := []bson.M{} itemID := fmt.Sprintf("%v", item["_id"]) userID := fmt.Sprintf("%v", item["_userId"]) itemType := fmt.Sprintf("%v", item["type"]) + if rollback, ok := item["_rollbackJellyfishMigration"].(primitive.A); ok { + log.Printf("_rollbackJellyfishMigration [%s] %#v", itemID, rollback) + for _, cmd := range rollback { + if cmd, ok := cmd.(bson.M); ok { + cmds = append(cmds, cmd) + } + } + } + if len(cmds) > 0 { + m.migrationUtil.SetUpdates(utils.UpdateData{ + Filter: bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}, + ItemID: itemID, + UserID: userID, + ItemType: itemType, + Apply: cmds, + }, true) + } - m.migrationUtil.SetUpdates(utils.UpdateData{ - Filter: bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}, - ItemID: itemID, - UserID: userID, - ItemType: itemType, - Apply: rollbackCmds, - }, true) m.migrationUtil.SetLastProcessed(itemID) } m.migrationUtil.SetFetched(all) From 57ba478c7dc566afdcc9b3ae4f0431e46efd31d0 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 12 Mar 2024 16:05:11 +1300 Subject: [PATCH 268/413] log only if commands are found --- .../jellyfish_migration.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index a9df6f37b8..bf7717e3db 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -90,12 +90,13 @@ func (m *Migration) RunAndExit() { return err } return nil + } else { + if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndProcess); err != nil { + log.Printf("processing failed: %s", err) + return err + } + return nil } - if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndProcess); err != nil { - log.Printf("processing failed: %s", err) - return err - } - return nil } if err := m.CLI().Run(os.Args); err != nil { @@ -278,7 +279,6 @@ func (m *Migration) fetchAndRevert() bool { // jellyfish uses a generated _id that is not an mongo objectId idNotObjectID := bson.M{"$not": bson.M{"$type": "objectId"}} - if lastID := m.migrationUtil.GetLastID(); lastID != "" { selector["$and"] = []interface{}{ bson.M{"_id": bson.M{"$gt": lastID}}, @@ -318,14 +318,14 @@ func (m *Migration) fetchAndRevert() bool { userID := fmt.Sprintf("%v", item["_userId"]) itemType := fmt.Sprintf("%v", item["type"]) if rollback, ok := item["_rollbackJellyfishMigration"].(primitive.A); ok { - log.Printf("_rollbackJellyfishMigration [%s] %#v", itemID, rollback) for _, cmd := range rollback { - if cmd, ok := cmd.(bson.M); ok { + if cmd, ok := cmd.(primitive.M); ok { cmds = append(cmds, cmd) } } } if len(cmds) > 0 { + log.Printf("_rollbackJellyfishMigration [%s] %#v", itemID, cmds) m.migrationUtil.SetUpdates(utils.UpdateData{ Filter: bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}, ItemID: itemID, @@ -334,8 +334,8 @@ func (m *Migration) fetchAndRevert() bool { Apply: cmds, }, true) } - m.migrationUtil.SetLastProcessed(itemID) + all = append(all, item) } m.migrationUtil.SetFetched(all) return len(all) > 0 From 4db4699f3b4637e5204f94c8e8b1876a2ca5a915 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 12 Mar 2024 17:09:07 +1300 Subject: [PATCH 269/413] update logging details --- .../20231128_jellyfish_migration/utils/migrationUtil.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index fe218c4bbb..6762702c0e 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -137,11 +137,11 @@ func (m *migrationUtil) capReached() bool { if m.config.cap != nil { stats := m.GetStats() - percent := (float64(stats.Applied) * float64(100)) / float64(*m.config.cap) - log.Printf("processed %.1f %% of %d records", percent, *m.config.cap) + percent := (float64(stats.Fetched) * float64(100)) / float64(*m.config.cap) + log.Printf("processed %.0f %% of %d records and applied %d changes", percent, *m.config.cap, stats.Applied) if *m.config.cap <= stats.Applied || *m.config.cap <= stats.Fetched { - log.Printf("cap [%d] updated [%d] fetched [%d]", *m.config.cap, stats.Applied, stats.Fetched) + log.Printf("cap [%d] updates applied [%d] fetched [%d]", *m.config.cap, stats.Applied, stats.Fetched) return true } } From 5ab390b33f28508053cea4c149af087a5959c7eb Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 13 Mar 2024 12:00:31 +1300 Subject: [PATCH 270/413] naming updates for consistency --- .../jellyfish_migration.go | 58 +++++++++++-------- ...ion.sh => rollback_jellyfish_migration.sh} | 2 +- .../search_errors.sh | 4 +- .../utils/migrationUtil.go | 48 ++++++++------- 4 files changed, 65 insertions(+), 47 deletions(-) rename migrations/20231128_jellyfish_migration/{revert_jellyfish_migration.sh => rollback_jellyfish_migration.sh} (62%) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index bf7717e3db..6640ce5e65 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -25,16 +25,17 @@ type Migration struct { } type config struct { - cap int - uri string - dryRun bool - stopOnErr bool - revertChanges bool - userID string - lastUpdatedId string - nopPercent int - queryBatchSize int64 - queryLimit int64 + cap int + uri string + dryRun bool + stopOnErr bool + rollback bool + rollbackSectionName string + userID string + lastUpdatedId string + nopPercent int + queryBatchSize int64 + queryLimit int64 } const DryRunFlag = "dry-run" @@ -50,9 +51,11 @@ func main() { func NewMigration(ctx context.Context) *Migration { return &Migration{ - config: &config{}, - ctx: ctx, - cli: cli.NewApp(), + config: &config{ + rollbackSectionName: "_rollbackJellyfishMigration", + }, + ctx: ctx, + cli: cli.NewApp(), } } @@ -69,9 +72,14 @@ func (m *Migration) RunAndExit() { return fmt.Errorf("unable to connect to MongoDB: %w", err) } defer m.client.Disconnect(m.ctx) - cap := m.config.cap m.migrationUtil, err = utils.NewMigrationUtil( - utils.NewMigrationUtilConfig(&m.config.dryRun, &m.config.stopOnErr, &m.config.revertChanges, &m.config.nopPercent, &cap), + utils.NewMigrationUtilConfig( + &m.config.dryRun, + &m.config.stopOnErr, + &m.config.rollback, + &m.config.rollbackSectionName, + &m.config.nopPercent, + &m.config.cap), m.client, &m.config.lastUpdatedId, ) @@ -84,7 +92,7 @@ func (m *Migration) RunAndExit() { return err } - if m.config.revertChanges { + if m.config.rollback { if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndRevert); err != nil { log.Printf("revert failed: %s", err) return err @@ -128,9 +136,9 @@ func (m *Migration) Initialize() error { Destination: &m.config.stopOnErr, }, cli.BoolFlag{ - Name: "revert-changes", - Usage: "revert migration changes that have been applied", - Destination: &m.config.revertChanges, + Name: "rollback", + Usage: "rollback migration changes that have been applied", + Destination: &m.config.rollback, }, cli.IntFlag{ Name: "cap", @@ -255,7 +263,7 @@ func (m *Migration) fetchAndProcess() bool { ItemType: itemType, Apply: updates, Revert: revert, - }, false) + }) } m.migrationUtil.SetLastProcessed(itemID) all = append(all, item) @@ -268,8 +276,10 @@ func (m *Migration) fetchAndProcess() bool { func (m *Migration) fetchAndRevert() bool { + rollbackValues := m.config.rollbackSectionName + selector := bson.M{ - "_rollbackJellyfishMigration": bson.M{"$exists": true}, + rollbackValues: bson.M{"$exists": true}, } if strings.TrimSpace(m.config.userID) != "" { @@ -317,7 +327,7 @@ func (m *Migration) fetchAndRevert() bool { itemID := fmt.Sprintf("%v", item["_id"]) userID := fmt.Sprintf("%v", item["_userId"]) itemType := fmt.Sprintf("%v", item["type"]) - if rollback, ok := item["_rollbackJellyfishMigration"].(primitive.A); ok { + if rollback, ok := item[rollbackValues].(primitive.A); ok { for _, cmd := range rollback { if cmd, ok := cmd.(primitive.M); ok { cmds = append(cmds, cmd) @@ -325,14 +335,14 @@ func (m *Migration) fetchAndRevert() bool { } } if len(cmds) > 0 { - log.Printf("_rollbackJellyfishMigration [%s] %#v", itemID, cmds) + log.Printf("%s [%s] %#v", rollbackValues, itemID, cmds) m.migrationUtil.SetUpdates(utils.UpdateData{ Filter: bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}, ItemID: itemID, UserID: userID, ItemType: itemType, Apply: cmds, - }, true) + }) } m.migrationUtil.SetLastProcessed(itemID) all = append(all, item) diff --git a/migrations/20231128_jellyfish_migration/revert_jellyfish_migration.sh b/migrations/20231128_jellyfish_migration/rollback_jellyfish_migration.sh similarity index 62% rename from migrations/20231128_jellyfish_migration/revert_jellyfish_migration.sh rename to migrations/20231128_jellyfish_migration/rollback_jellyfish_migration.sh index de2059af8e..1bf656a592 100644 --- a/migrations/20231128_jellyfish_migration/revert_jellyfish_migration.sh +++ b/migrations/20231128_jellyfish_migration/rollback_jellyfish_migration.sh @@ -1,3 +1,3 @@ #!/bin/bash -go run jellyfish_migration.go --cap=500000 --nop-percent=1 --query-limit=100 --query-batch=50 --revert-changes +go run jellyfish_migration.go --cap=500000 --nop-percent=1 --query-limit=100 --query-batch=50 --rollback diff --git a/migrations/20231128_jellyfish_migration/search_errors.sh b/migrations/20231128_jellyfish_migration/search_errors.sh index ce41d81966..bda290a6e0 100644 --- a/migrations/20231128_jellyfish_migration/search_errors.sh +++ b/migrations/20231128_jellyfish_migration/search_errors.sh @@ -12,7 +12,7 @@ echo "exclude error code: $EXCLUDE_TXT" jq -cnr '(reduce inputs as $line ([]; . + [$line]))' $INPUT_FILE >$TMP_FILE if [[ -z "$EXCLUDE_TXT" ]]; then - jq -c "map(.)|unique_by(.error.detail)|.[]|{"id":._id,"detail":.error.detail,"code":.error.code}" $TMP_FILE >$OUTPUT_FILE + jq -c "map(.)|unique_by(.error.detail)|.[]|{"id":._id,"detail":.error.detail,"code":.error.code, "source":.error.source}" $TMP_FILE >$OUTPUT_FILE else - jq -c "map(.)|unique_by(.error.detail)|.[]|select(.error.detail!=null)|select(.error.detail|contains(\"$EXCLUDE_TXT\")|not)|.[]|{"id":._id,"detail":.error.detail,"code":.error.code}" $TMP_FILE >$OUTPUT_FILE + jq -c "map(.)|unique_by(.error.detail)|.[]|select(.error.detail!=null)|select(.error.detail|contains(\"$EXCLUDE_TXT\")|not)|.[]|{"id":._id,"detail":.error.detail,"code":.error.code, "source":.error.source}" $TMP_FILE >$OUTPUT_FILE fi diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go index 6762702c0e..e7f7a40db8 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationUtil.go @@ -20,8 +20,10 @@ import ( type MigrationUtilConfig struct { //apply no changes dryRun bool - //revert the changes that have been applied - revertChanges bool + //rollback the changes that have been applied + rollback bool + //name of section with mongo document that stores the original values + rollbackSectionName string //halt on error stopOnErr bool minOplogWindow int @@ -84,7 +86,7 @@ type MigrationUtil interface { Initialize(ctx context.Context, dataC *mongo.Collection) error Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func() bool) error OnError(data ErrorData) - SetUpdates(data UpdateData, asRollback bool) + SetUpdates(data UpdateData) SetLastProcessed(lastID string) SetFetched(raw []bson.M) GetLastID() string @@ -157,7 +159,6 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe if m.capReached() { break } - } m.GetStats().report() m.writeErrors(nil) @@ -165,7 +166,7 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe return nil } -func (d UpdateData) getDatumUpdates(asRollback bool) []mongo.WriteModel { +func (d UpdateData) getDatumUpdates(rollback bool, rollbackSectionName string) []mongo.WriteModel { updates := []mongo.WriteModel{} for _, u := range d.Apply { updateOp := mongo.NewUpdateOneModel() @@ -175,18 +176,18 @@ func (d UpdateData) getDatumUpdates(asRollback bool) []mongo.WriteModel { } updateOp := mongo.NewUpdateOneModel() updateOp.Filter = d.Filter - if !asRollback && len(d.Revert) > 0 { - updateOp.SetUpdate(bson.M{"$set": bson.M{"_rollbackJellyfishMigration": d.Revert}}) - } else if asRollback { - updateOp.SetUpdate(bson.M{"$unset": bson.M{"_rollbackJellyfishMigration": ""}}) + if !rollback && len(d.Revert) > 0 { + updateOp.SetUpdate(bson.M{"$set": bson.M{rollbackSectionName: d.Revert}}) + } else if rollback { + updateOp.SetUpdate(bson.M{"$unset": bson.M{rollbackSectionName: ""}}) } updates = append(updates, updateOp) return updates } -func (m *migrationUtil) SetUpdates(data UpdateData, asRollback bool) { +func (m *migrationUtil) SetUpdates(data UpdateData) { m.groupedDiffs[data.ItemType] = append(m.groupedDiffs[data.ItemType], data) - m.updates = append(m.updates, data.getDatumUpdates(asRollback)...) + m.updates = append(m.updates, data.getDatumUpdates(m.config.rollback, m.config.rollbackSectionName)...) } func (m *migrationUtil) SetLastProcessed(lastID string) { @@ -194,8 +195,6 @@ func (m *migrationUtil) SetLastProcessed(lastID string) { } func createFile(fileType string, dataGroup string, logName string) (*os.File, error) { - datetime := time.Now().Round(15 * time.Minute) - datestamp := datetime.Format(time.DateOnly) var err error if fileType == "" { errors.Join(err, errors.New("missing file type")) @@ -210,7 +209,7 @@ func createFile(fileType string, dataGroup string, logName string) (*os.File, er return nil, err } logName = fmt.Sprintf(logName, dataGroup) - logPath := filepath.Join(".", fileType, datestamp) + logPath := filepath.Join(".", fileType) err = os.MkdirAll(logPath, os.ModePerm) if err != nil { @@ -301,12 +300,13 @@ func (m *migrationUtil) GetLastID() string { return m.lastUpdatedId } -func NewMigrationUtilConfig(dryRun *bool, stopOnErr *bool, revertChanges *bool, nopPercent *int, cap *int) *MigrationUtilConfig { +func NewMigrationUtilConfig(dryRun *bool, stopOnErr *bool, rollback *bool, rollbackSectionName *string, nopPercent *int, cap *int) *MigrationUtilConfig { cfg := &MigrationUtilConfig{ minOplogWindow: 28800, // 8hrs minFreePercent: 10, expectedOplogEntrySize: 420, - revertChanges: true, + rollback: true, + rollbackSectionName: "_rollbackMigration", dryRun: true, stopOnErr: true, nopPercent: 25, @@ -317,8 +317,11 @@ func NewMigrationUtilConfig(dryRun *bool, stopOnErr *bool, revertChanges *bool, if stopOnErr != nil { cfg.SetStopOnErr(*stopOnErr) } - if revertChanges != nil { - cfg.SetRevertChanges(*revertChanges) + if rollback != nil { + cfg.SetRollback(*rollback) + } + if rollbackSectionName != nil { + cfg.SetRollbackSectionName(*rollbackSectionName) } if nopPercent != nil { cfg.SetNopPercent(*nopPercent) @@ -356,8 +359,13 @@ func (c *MigrationUtilConfig) SetStopOnErr(stopOnErr bool) *MigrationUtilConfig return c } -func (c *MigrationUtilConfig) SetRevertChanges(revertChanges bool) *MigrationUtilConfig { - c.revertChanges = revertChanges +func (c *MigrationUtilConfig) SetRollback(rollback bool) *MigrationUtilConfig { + c.rollback = rollback + return c +} + +func (c *MigrationUtilConfig) SetRollbackSectionName(rollbackSectionName string) *MigrationUtilConfig { + c.rollbackSectionName = rollbackSectionName return c } From eab3f8d68fec2340fd4e74be69595106d4c34d4b Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 14 Mar 2024 19:08:43 +1300 Subject: [PATCH 271/413] rework for testing --- .../jellyfish_migration.go | 205 ++------ .../utils/jellyfish.go | 138 +++++ .../utils/migration.go | 155 ++++++ .../{migrationUtil.go => migrationImpl.go} | 470 ++++++------------ .../utils/migration_test.go | 236 +++++++++ 5 files changed, 723 insertions(+), 481 deletions(-) create mode 100644 migrations/20231128_jellyfish_migration/utils/jellyfish.go create mode 100644 migrations/20231128_jellyfish_migration/utils/migration.go rename migrations/20231128_jellyfish_migration/utils/{migrationUtil.go => migrationImpl.go} (58%) create mode 100644 migrations/20231128_jellyfish_migration/utils/migration_test.go diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 6640ce5e65..154ea70454 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -8,8 +8,6 @@ import ( "strings" "github.com/urfave/cli" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" @@ -21,7 +19,7 @@ type Migration struct { cli *cli.App config *config client *mongo.Client - migrationUtil utils.MigrationUtil + migrationUtil utils.Migration } type config struct { @@ -44,12 +42,12 @@ func main() { ctx := context.Background() ctx, cancel := context.WithCancel(ctx) defer cancel() - migration := NewMigration(ctx) + migration := NewJellyfishMigration(ctx) migration.RunAndExit() log.Println("finished migration") } -func NewMigration(ctx context.Context) *Migration { +func NewJellyfishMigration(ctx context.Context) *Migration { return &Migration{ config: &config{ rollbackSectionName: "_rollbackJellyfishMigration", @@ -72,8 +70,9 @@ func (m *Migration) RunAndExit() { return fmt.Errorf("unable to connect to MongoDB: %w", err) } defer m.client.Disconnect(m.ctx) - m.migrationUtil, err = utils.NewMigrationUtil( - utils.NewMigrationUtilConfig( + m.migrationUtil, err = utils.NewMigration( + m.ctx, + utils.NewMigrationConfig( &m.config.dryRun, &m.config.stopOnErr, &m.config.rollback, @@ -81,30 +80,40 @@ func (m *Migration) RunAndExit() { &m.config.nopPercent, &m.config.cap), m.client, + m.client.Database("data").Collection("deviceData"), &m.config.lastUpdatedId, ) if err != nil { - return fmt.Errorf("unable init migration utils : %w", err) + return fmt.Errorf("unable to create migration utils : %w", err) } - if err := m.migrationUtil.Initialize(m.ctx, m.getDataCollection()); err != nil { + if err := m.migrationUtil.Initialize(); err != nil { log.Printf("prepare failed: %s", err) return err } + lastFetchedID := m.migrationUtil.GetLastID() + + selector, opt := utils.JellyfishUpdatesQuery( + &m.config.userID, + &lastFetchedID, + m.config.queryBatchSize, + m.config.queryLimit, + ) if m.config.rollback { - if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndRevert); err != nil { - log.Printf("revert failed: %s", err) - return err - } - return nil - } else { - if err := m.migrationUtil.Execute(m.ctx, m.getDataCollection(), m.fetchAndProcess); err != nil { - log.Printf("processing failed: %s", err) - return err - } - return nil + selector, opt = utils.JellyfishRollbackQuery( + m.config.rollbackSectionName, + &m.config.userID, + &lastFetchedID, + m.config.queryBatchSize, + m.config.queryLimit, + ) + } + if err := m.migrationUtil.Execute(selector, opt, utils.ProcessJellyfishQueryFn, utils.WriteJellyfishUpdatesFn); err != nil { + log.Printf("execute failed: %s", err) + return err } + return nil } if err := m.CLI().Run(os.Args); err != nil { @@ -196,159 +205,3 @@ func (m *Migration) Initialize() error { func (m *Migration) CLI() *cli.App { return m.cli } - -func (m *Migration) getDataCollection() *mongo.Collection { - return m.client.Database("data").Collection("deviceData") -} - -func (m *Migration) fetchAndProcess() bool { - - selector := bson.M{ - "_deduplicator": bson.M{"$exists": false}, - } - - if strings.TrimSpace(m.config.userID) != "" { - log.Printf("fetching for user %s", m.config.userID) - selector["_userId"] = m.config.userID - } - - // jellyfish uses a generated _id that is not an mongo objectId - idNotObjectID := bson.M{"$not": bson.M{"$type": "objectId"}} - - if lastID := m.migrationUtil.GetLastID(); lastID != "" { - selector["$and"] = []interface{}{ - bson.M{"_id": bson.M{"$gt": lastID}}, - bson.M{"_id": idNotObjectID}, - } - } else { - selector["_id"] = idNotObjectID - } - - batchSize := int32(m.config.queryBatchSize) - - if dataC := m.getDataCollection(); dataC != nil { - - dDataCursor, err := dataC.Find(m.ctx, selector, - &options.FindOptions{ - Sort: bson.M{"_id": 1}, - BatchSize: &batchSize, - Limit: &m.config.queryLimit, - }, - ) - if err != nil { - log.Printf("failed to select data: %s", err) - return false - } - defer dDataCursor.Close(m.ctx) - - all := []bson.M{} - - for dDataCursor.Next(m.ctx) { - item := bson.M{} - if err := dDataCursor.Decode(&item); err != nil { - log.Printf("error decoding data: %s", err) - return false - } - itemID := fmt.Sprintf("%v", item["_id"]) - userID := fmt.Sprintf("%v", item["_userId"]) - itemType := fmt.Sprintf("%v", item["type"]) - updates, revert, err := utils.ProcessDatum(itemID, itemType, item) - if err != nil { - m.migrationUtil.OnError(utils.ErrorData{Error: err, ItemID: itemID, ItemType: itemType}) - } else if len(updates) > 0 { - m.migrationUtil.SetUpdates(utils.UpdateData{ - Filter: bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}, - ItemID: itemID, - UserID: userID, - ItemType: itemType, - Apply: updates, - Revert: revert, - }) - } - m.migrationUtil.SetLastProcessed(itemID) - all = append(all, item) - } - m.migrationUtil.SetFetched(all) - return len(all) > 0 - } - return false -} - -func (m *Migration) fetchAndRevert() bool { - - rollbackValues := m.config.rollbackSectionName - - selector := bson.M{ - rollbackValues: bson.M{"$exists": true}, - } - - if strings.TrimSpace(m.config.userID) != "" { - log.Printf("fetching for user %s", m.config.userID) - selector["_userId"] = m.config.userID - } - - // jellyfish uses a generated _id that is not an mongo objectId - idNotObjectID := bson.M{"$not": bson.M{"$type": "objectId"}} - if lastID := m.migrationUtil.GetLastID(); lastID != "" { - selector["$and"] = []interface{}{ - bson.M{"_id": bson.M{"$gt": lastID}}, - bson.M{"_id": idNotObjectID}, - } - } else { - selector["_id"] = idNotObjectID - } - - batchSize := int32(m.config.queryBatchSize) - - if dataC := m.getDataCollection(); dataC != nil { - - dDataCursor, err := dataC.Find(m.ctx, selector, - &options.FindOptions{ - Sort: bson.M{"_id": 1}, - BatchSize: &batchSize, - Limit: &m.config.queryLimit, - }, - ) - if err != nil { - log.Printf("failed to select data: %s", err) - return false - } - defer dDataCursor.Close(m.ctx) - - all := []bson.M{} - - for dDataCursor.Next(m.ctx) { - item := bson.M{} - if err := dDataCursor.Decode(&item); err != nil { - log.Printf("error decoding data: %s", err) - return false - } - cmds := []bson.M{} - itemID := fmt.Sprintf("%v", item["_id"]) - userID := fmt.Sprintf("%v", item["_userId"]) - itemType := fmt.Sprintf("%v", item["type"]) - if rollback, ok := item[rollbackValues].(primitive.A); ok { - for _, cmd := range rollback { - if cmd, ok := cmd.(primitive.M); ok { - cmds = append(cmds, cmd) - } - } - } - if len(cmds) > 0 { - log.Printf("%s [%s] %#v", rollbackValues, itemID, cmds) - m.migrationUtil.SetUpdates(utils.UpdateData{ - Filter: bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}, - ItemID: itemID, - UserID: userID, - ItemType: itemType, - Apply: cmds, - }) - } - m.migrationUtil.SetLastProcessed(itemID) - all = append(all, item) - } - m.migrationUtil.SetFetched(all) - return len(all) > 0 - } - return false -} diff --git a/migrations/20231128_jellyfish_migration/utils/jellyfish.go b/migrations/20231128_jellyfish_migration/utils/jellyfish.go new file mode 100644 index 0000000000..69f3046b09 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/utils/jellyfish.go @@ -0,0 +1,138 @@ +package utils + +import ( + "errors" + "fmt" + "log" + + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + +func commonQuery(selector bson.M, userID *string, lastFetchedID *string) { + if userID != nil { + log.Printf("fetching for user %s", *userID) + selector["_userId"] = *userID + } + idNotObjectID := bson.M{"$not": bson.M{"$type": "objectId"}} + + if lastFetchedID != nil { + selector["$and"] = []interface{}{ + bson.M{"_id": bson.M{"$gt": *lastFetchedID}}, + bson.M{"_id": idNotObjectID}, + } + } else { + selector["_id"] = idNotObjectID + } +} + +func opt(batchSize int32, queryLimit int64) *options.FindOptions { + return &options.FindOptions{ + Sort: bson.M{"_id": 1}, + BatchSize: &batchSize, + Limit: &queryLimit, + } +} + +func JellyfishUpdatesQuery(userID *string, lastFetchedID *string, batchSize int64, queryLimit int64) (bson.M, *options.FindOptions) { + selector := bson.M{ + "_deduplicator": bson.M{"$exists": false}, + } + commonQuery(selector, userID, lastFetchedID) + return selector, opt(int32(batchSize), queryLimit) +} + +func JellyfishRollbackQuery(rollbackSectionName string, userID *string, lastFetchedID *string, batchSize int64, queryLimit int64) (bson.M, *options.FindOptions) { + selector := bson.M{ + rollbackSectionName: bson.M{"$exists": true}, + } + commonQuery(selector, userID, lastFetchedID) + return selector, opt(int32(batchSize), queryLimit) +} + +var ProcessJellyfishQueryFn = func(m Migration, selector bson.M, opts ...*options.FindOptions) bool { + if dataC := m.GetDataCollection(); dataC != nil { + dDataCursor, err := dataC.Find(m.GetCtx(), selector, opts...) + if err != nil { + log.Printf("failed to select data: %s", err) + return false + } + defer dDataCursor.Close(m.GetCtx()) + + all := []bson.M{} + + for dDataCursor.Next(m.GetCtx()) { + item := bson.M{} + if err := dDataCursor.Decode(&item); err != nil { + log.Printf("error decoding data: %s", err) + return false + } + itemID := fmt.Sprintf("%v", item["_id"]) + userID := fmt.Sprintf("%v", item["_userId"]) + itemType := fmt.Sprintf("%v", item["type"]) + updates, revert, err := ProcessDatum(itemID, itemType, item) + if err != nil { + m.OnError(ErrorData{Error: err, ItemID: itemID, ItemType: itemType}) + } else if len(updates) > 0 { + m.SetUpdates(UpdateData{ + Filter: bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}, + ItemID: itemID, + UserID: userID, + ItemType: itemType, + Apply: updates, + Revert: revert, + }) + } + m.SetLastProcessed(itemID) + all = append(all, item) + } + m.SetFetched(all) + return len(all) > 0 + } + return false +} + +var WriteJellyfishUpdatesFn = func(m Migration) (int, error) { + settings := m.GetSettings() + updates := m.GetUpdates() + dataC := m.GetDataCollection() + if dataC == nil { + return 0, errors.New("missing required collection to write updates to") + } + if len(m.GetUpdates()) == 0 { + return 0, nil + } + + var getBatches = func(chunkSize int) [][]mongo.WriteModel { + batches := [][]mongo.WriteModel{} + for i := 0; i < len(updates); i += chunkSize { + end := i + chunkSize + if end > len(updates) { + end = len(updates) + } + batches = append(batches, updates[i:end]) + } + return batches + } + writtenCount := 0 + for _, batch := range getBatches(int(*settings.WriteBatchSize)) { + + if err := m.UpdateChecks(); err != nil { + return writtenCount, err + } + + if settings.DryRun { + writtenCount += len(batch) + continue + } + results, err := dataC.BulkWrite(m.GetCtx(), batch) + if err != nil { + log.Printf("error writing batch updates %v", err) + return writtenCount, err + } + writtenCount += int(results.ModifiedCount) + } + m.ResetUpdates() + return writtenCount, nil +} diff --git a/migrations/20231128_jellyfish_migration/utils/migration.go b/migrations/20231128_jellyfish_migration/utils/migration.go new file mode 100644 index 0000000000..d36edad323 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/utils/migration.go @@ -0,0 +1,155 @@ +package utils + +import ( + "context" + "log" + "time" + + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + +type UpdateData struct { + Filter interface{} `json:"-"` + ItemID string `json:"_id"` + UserID string `json:"_userId"` + ItemType string `json:"-"` + Apply []bson.M `json:"apply"` + ApplyLast bson.M `json:"applyLast"` + Revert []bson.M `json:"revert"` +} + +type ErrorData struct { + Error error `json:"error"` + ItemID string `json:"_id"` + ItemType string `json:"-"` + Msg string `json:"message,omitempty"` +} + +type MigrationStats struct { + Errored int + Fetched int + Applied int + ToApply int + Elapsed time.Duration +} + +type MigrationQueryFn = func(mUtil Migration, selector bson.M, opts ...*options.FindOptions) bool + +type MigrationUpdateFn = func(mUtil Migration) (int, error) + +type Migration interface { + Initialize() error + Execute(selector bson.M, opt *options.FindOptions, queryFn MigrationQueryFn, updateFn MigrationUpdateFn) error + GetSettings() Settings + GetLastID() string + UpdateChecks() error + GetCtx() context.Context + GetDataCollection() *mongo.Collection + OnError(data ErrorData) + SetUpdates(data UpdateData) + GetUpdates() []mongo.WriteModel + ResetUpdates() + SetLastProcessed(lastID string) + SetFetched(raw []bson.M) +} + +type Settings struct { + DryRun bool + Rollback bool + RollbackSectionName string + StopOnErr bool + Cap *int + WriteBatchSize *int64 +} + +type MigrationConfig struct { + //apply no changes + dryRun bool + //rollback the changes that have been applied + rollback bool + //name of section with mongo document that stores the original values + rollbackSectionName string + //halt on error + stopOnErr bool + minOplogWindow int + // these values are used to determine writes batches, first dividing the oplog's size with the desired duration and + // expected entry size, then adding a divisor to account for NOP overshoot in the oplog + expectedOplogEntrySize int + // how much of the oplog is NOP, this adjusts the batch to account for an oplog that is very change sensitive + // must be > 0 + // prod 0.6 + // idle 100 + nopPercent int + // minimum free disk space percent + minFreePercent int + // cap for number of items to migrate + cap *int +} + +func NewMigrationConfig(dryRun *bool, stopOnErr *bool, rollback *bool, rollbackSectionName *string, nopPercent *int, cap *int) *MigrationConfig { + cfg := &MigrationConfig{ + minOplogWindow: 28800, // 8hrs + minFreePercent: 10, + expectedOplogEntrySize: 420, + rollback: true, + rollbackSectionName: "_rollbackMigration", + dryRun: true, + stopOnErr: true, + nopPercent: 25, + } + if dryRun != nil { + cfg.SetDryRun(*dryRun) + } + if stopOnErr != nil { + cfg.SetStopOnErr(*stopOnErr) + } + if rollback != nil { + cfg.SetRollback(*rollback) + } + if rollbackSectionName != nil { + cfg.SetRollbackSectionName(*rollbackSectionName) + } + if nopPercent != nil { + cfg.SetNopPercent(*nopPercent) + } + if cap != nil && *cap > 0 { + cfg.cap = cap + log.Printf("capped at %d items", *cfg.cap) + } + return cfg +} + +func (c *MigrationConfig) SetNopPercent(nopPercent int) *MigrationConfig { + c.nopPercent = nopPercent + return c +} +func (c *MigrationConfig) SetMinOplogWindow(minOplogWindow int) *MigrationConfig { + c.minOplogWindow = minOplogWindow + return c +} +func (c *MigrationConfig) SetExpectedOplogEntrySize(expectedOplogEntrySize int) *MigrationConfig { + c.expectedOplogEntrySize = expectedOplogEntrySize + return c +} +func (c *MigrationConfig) SetMinFreePercent(minFreePercent int) *MigrationConfig { + c.minFreePercent = minFreePercent + return c +} +func (c *MigrationConfig) SetDryRun(dryRun bool) *MigrationConfig { + c.dryRun = dryRun + return c +} +func (c *MigrationConfig) SetStopOnErr(stopOnErr bool) *MigrationConfig { + c.stopOnErr = stopOnErr + return c +} +func (c *MigrationConfig) SetRollback(rollback bool) *MigrationConfig { + c.rollback = rollback + return c +} +func (c *MigrationConfig) SetRollbackSectionName(rollbackSectionName string) *MigrationConfig { + c.rollbackSectionName = rollbackSectionName + return c +} diff --git a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go b/migrations/20231128_jellyfish_migration/utils/migrationImpl.go similarity index 58% rename from migrations/20231128_jellyfish_migration/utils/migrationUtil.go rename to migrations/20231128_jellyfish_migration/utils/migrationImpl.go index e7f7a40db8..3abcbb53ea 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationUtil.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationImpl.go @@ -17,34 +17,12 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" ) -type MigrationUtilConfig struct { - //apply no changes - dryRun bool - //rollback the changes that have been applied - rollback bool - //name of section with mongo document that stores the original values - rollbackSectionName string - //halt on error - stopOnErr bool - minOplogWindow int - // these values are used to determine writes batches, first dividing the oplog's size with the desired duration and - // expected entry size, then adding a divisor to account for NOP overshoot in the oplog - expectedOplogEntrySize int - // how much of the oplog is NOP, this adjusts the batch to account for an oplog that is very change sensitive - // must be > 0 - // prod 0.6 - // idle 100 - nopPercent int - // minimum free disk space percent - minFreePercent int - // cap for number of items to migrate - cap *int -} - -type migrationUtil struct { +type migrationImpl struct { + ctx context.Context + dataC *mongo.Collection writeBatchSize *int64 client *mongo.Client - config *MigrationUtilConfig + config *MigrationConfig updates []mongo.WriteModel groupedDiffs map[string][]UpdateData groupedErrors groupedErrors @@ -55,47 +33,9 @@ type migrationUtil struct { startedAt time.Time } -type UpdateData struct { - Filter interface{} `json:"-"` - ItemID string `json:"_id"` - UserID string `json:"_userId"` - ItemType string `json:"-"` - Apply []bson.M `json:"apply"` - ApplyLast bson.M `json:"applyLast"` - Revert []bson.M `json:"revert"` -} - -type ErrorData struct { - Error error `json:"error"` - ItemID string `json:"_id"` - ItemType string `json:"-"` - Msg string `json:"message,omitempty"` -} - type groupedErrors map[string][]ErrorData -type MigrationStats struct { - Errored int - Fetched int - Applied int - ToApply int - Elapsed time.Duration -} - -type MigrationUtil interface { - Initialize(ctx context.Context, dataC *mongo.Collection) error - Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func() bool) error - OnError(data ErrorData) - SetUpdates(data UpdateData) - SetLastProcessed(lastID string) - SetFetched(raw []bson.M) - GetLastID() string - GetStats() MigrationStats -} - -// MigrationUtil helps managed the migration process -// errors written to -func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client, lastID *string) (MigrationUtil, error) { +func NewMigration(ctx context.Context, config *MigrationConfig, client *mongo.Client, dataC *mongo.Collection, lastID *string) (Migration, error) { var err error if config == nil { err = errors.Join(err, errors.New("missing required configuration")) @@ -108,7 +48,9 @@ func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client, lastID return nil, err } - m := &migrationUtil{ + m := &migrationImpl{ + ctx: ctx, + dataC: dataC, client: client, config: config, updates: []mongo.WriteModel{}, @@ -125,34 +67,44 @@ func NewMigrationUtil(config *MigrationUtilConfig, client *mongo.Client, lastID return m, nil } -func (m *migrationUtil) Initialize(ctx context.Context, dataC *mongo.Collection) error { - if err := m.checkFreeSpace(ctx, dataC); err != nil { +func (m *migrationImpl) Initialize() error { + if err := m.checkFreeSpace(m.ctx, m.dataC); err != nil { return err } - if err := m.setWriteBatchSize(ctx); err != nil { + if err := m.setWriteBatchSize(m.ctx); err != nil { return err } return nil } -func (m *migrationUtil) capReached() bool { - if m.config.cap != nil { - stats := m.GetStats() - - percent := (float64(stats.Fetched) * float64(100)) / float64(*m.config.cap) - log.Printf("processed %.0f %% of %d records and applied %d changes", percent, *m.config.cap, stats.Applied) +func (m *migrationImpl) GetCtx() context.Context { + return m.ctx +} - if *m.config.cap <= stats.Applied || *m.config.cap <= stats.Fetched { - log.Printf("cap [%d] updates applied [%d] fetched [%d]", *m.config.cap, stats.Applied, stats.Fetched) - return true - } +func (m *migrationImpl) GetSettings() Settings { + return Settings{ + DryRun: m.config.dryRun, + Rollback: m.config.rollback, + RollbackSectionName: m.config.rollbackSectionName, + Cap: m.config.cap, + StopOnErr: m.config.stopOnErr, + WriteBatchSize: m.writeBatchSize, } - return false } -func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fetchAndUpdateFn func() bool) error { - for fetchAndUpdateFn() { - if err := m.writeUpdates(ctx, dataC); err != nil { +func (m *migrationImpl) GetDataCollection() *mongo.Collection { + return m.dataC +} + +func (m *migrationImpl) Execute( + selector bson.M, + selectorOpt *options.FindOptions, + queryFn MigrationQueryFn, + updateFn MigrationUpdateFn) error { + for queryFn(m, selector, selectorOpt) { + var err error + m.updatedCount, err = updateFn(m) + if err != nil { m.writeErrors(nil) return err } @@ -160,13 +112,13 @@ func (m *migrationUtil) Execute(ctx context.Context, dataC *mongo.Collection, fe break } } - m.GetStats().report() + m.getStats().report() m.writeErrors(nil) m.writeAudit(nil) return nil } -func (d UpdateData) getDatumUpdates(rollback bool, rollbackSectionName string) []mongo.WriteModel { +func (d UpdateData) GetMongoUpdates(rollback bool, rollbackSectionName string) []mongo.WriteModel { updates := []mongo.WriteModel{} for _, u := range d.Apply { updateOp := mongo.NewUpdateOneModel() @@ -185,100 +137,29 @@ func (d UpdateData) getDatumUpdates(rollback bool, rollbackSectionName string) [ return updates } -func (m *migrationUtil) SetUpdates(data UpdateData) { +func (m *migrationImpl) SetUpdates(data UpdateData) { m.groupedDiffs[data.ItemType] = append(m.groupedDiffs[data.ItemType], data) - m.updates = append(m.updates, data.getDatumUpdates(m.config.rollback, m.config.rollbackSectionName)...) + m.updates = append(m.updates, data.GetMongoUpdates(m.config.rollback, m.config.rollbackSectionName)...) } -func (m *migrationUtil) SetLastProcessed(lastID string) { - m.lastUpdatedId = lastID +func (m *migrationImpl) ResetUpdates() { + m.updates = []mongo.WriteModel{} } -func createFile(fileType string, dataGroup string, logName string) (*os.File, error) { - var err error - if fileType == "" { - errors.Join(err, errors.New("missing file type")) - } - if dataGroup == "" { - errors.Join(err, errors.New("missing data group")) - } - if logName == "" { - errors.Join(err, errors.New("missing log group")) - } - if err != nil { - return nil, err - } - logName = fmt.Sprintf(logName, dataGroup) - logPath := filepath.Join(".", fileType) - - err = os.MkdirAll(logPath, os.ModePerm) - if err != nil { - return nil, err - } - return os.OpenFile(logPath+"/"+logName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) +func (m *migrationImpl) GetUpdates() []mongo.WriteModel { + return m.updates } -func (m *migrationUtil) writeErrors(groupLimit *int) { - for group, errors := range m.groupedErrors { - if groupLimit != nil { - if len(errors) < *groupLimit { - continue - } - } - f, err := createFile("error", group, "%s.log") - if err != nil { - log.Println(err) - os.Exit(1) - } - defer f.Close() - for _, data := range errors { - errJSON, err := json.Marshal(data) - if err != nil { - log.Println(err) - os.Exit(1) - } - f.WriteString(string(errJSON) + "\n") - } - m.groupedErrors[group] = []ErrorData{} - } -} - -func (m *migrationUtil) writeAudit(groupLimit *int) { - - if !m.config.dryRun { - m.groupedDiffs = map[string][]UpdateData{} - return - } - - for group, diffs := range m.groupedDiffs { - if groupLimit != nil { - if len(diffs) < *groupLimit { - continue - } - } - f, err := createFile("audit", group, "%s.json") - if err != nil { - log.Println(err) - os.Exit(1) - } - defer f.Close() - for _, data := range diffs { - diffJSON, err := json.Marshal(data) - if err != nil { - log.Println(err) - os.Exit(1) - } - f.WriteString(string(diffJSON) + "\n") - } - m.groupedDiffs[group] = []UpdateData{} - } +func (m *migrationImpl) SetLastProcessed(lastID string) { + m.lastUpdatedId = lastID + writeLastProcessed(m.lastUpdatedId) } -func (m *migrationUtil) SetFetched(raw []bson.M) { +func (m *migrationImpl) SetFetched(raw []bson.M) { m.rawData = append(m.rawData, raw...) } -func (m *migrationUtil) GetStats() MigrationStats { +func (m *migrationImpl) getStats() MigrationStats { return MigrationStats{ Errored: m.errorsCount, Fetched: len(m.rawData), @@ -288,122 +169,63 @@ func (m *migrationUtil) GetStats() MigrationStats { } } -func (c MigrationStats) report() { - if c.Applied == 0 && c.Fetched > 0 { - log.Printf("elapsed [%s] for [%d] items fetched with [%d] errors\n", c.Elapsed, c.Fetched, c.Errored) - return - } - log.Printf("elapsed [%s] for [%d] items migrated with [%d] errors\n", c.Elapsed, c.Applied, c.Errored) -} - -func (m *migrationUtil) GetLastID() string { +func (m *migrationImpl) GetLastID() string { return m.lastUpdatedId } -func NewMigrationUtilConfig(dryRun *bool, stopOnErr *bool, rollback *bool, rollbackSectionName *string, nopPercent *int, cap *int) *MigrationUtilConfig { - cfg := &MigrationUtilConfig{ - minOplogWindow: 28800, // 8hrs - minFreePercent: 10, - expectedOplogEntrySize: 420, - rollback: true, - rollbackSectionName: "_rollbackMigration", - dryRun: true, - stopOnErr: true, - nopPercent: 25, - } - if dryRun != nil { - cfg.SetDryRun(*dryRun) - } - if stopOnErr != nil { - cfg.SetStopOnErr(*stopOnErr) - } - if rollback != nil { - cfg.SetRollback(*rollback) - } - if rollbackSectionName != nil { - cfg.SetRollbackSectionName(*rollbackSectionName) - } - if nopPercent != nil { - cfg.SetNopPercent(*nopPercent) - } - if cap != nil && *cap > 0 { - cfg.cap = cap - log.Printf("capped at %d items", *cfg.cap) +func (m *migrationImpl) OnError(data ErrorData) { + m.errorsCount++ + m.groupedErrors[data.ItemType] = append(m.groupedErrors[data.ItemType], data) + var errFormat = "[_id=%s] %s %s\n" + + if m.config.stopOnErr { + log.Printf(errFormat, data.ItemID, data.Msg, data.Error.Error()) + os.Exit(1) } - return cfg } -func (c *MigrationUtilConfig) SetNopPercent(nopPercent int) *MigrationUtilConfig { - c.nopPercent = nopPercent - return c +func (m *migrationImpl) UpdateChecks() error { + if err := m.blockUntilDBReady(m.GetCtx()); err != nil { + return err + } + if err := m.checkFreeSpace(m.GetCtx(), m.GetDataCollection()); err != nil { + return err + } + return nil } -func (c *MigrationUtilConfig) SetMinOplogWindow(minOplogWindow int) *MigrationUtilConfig { - c.minOplogWindow = minOplogWindow - return c -} -func (c *MigrationUtilConfig) SetExpectedOplogEntrySize(expectedOplogEntrySize int) *MigrationUtilConfig { - c.expectedOplogEntrySize = expectedOplogEntrySize - return c -} -func (c *MigrationUtilConfig) SetMinFreePercent(minFreePercent int) *MigrationUtilConfig { - c.minFreePercent = minFreePercent - return c -} -func (c *MigrationUtilConfig) SetDryRun(dryRun bool) *MigrationUtilConfig { - c.dryRun = dryRun - return c -} -func (c *MigrationUtilConfig) SetStopOnErr(stopOnErr bool) *MigrationUtilConfig { - c.stopOnErr = stopOnErr - return c -} +func (m *migrationImpl) capReached() bool { + if m.config.cap != nil { + stats := m.getStats() -func (c *MigrationUtilConfig) SetRollback(rollback bool) *MigrationUtilConfig { - c.rollback = rollback - return c -} + percent := (float64(stats.Fetched) * float64(100)) / float64(*m.config.cap) + log.Printf("processed %.0f %% of %d records and applied %d changes", percent, *m.config.cap, stats.Applied) -func (c *MigrationUtilConfig) SetRollbackSectionName(rollbackSectionName string) *MigrationUtilConfig { - c.rollbackSectionName = rollbackSectionName - return c + if *m.config.cap <= stats.Applied || *m.config.cap <= stats.Fetched { + log.Printf("cap [%d] updates applied [%d] fetched [%d]", *m.config.cap, stats.Applied, stats.Fetched) + return true + } + } + return false } -// OnError -// - write error to file `error.log` in directory cli is running in -// - optionally stop the operation if stopOnErr is true in the config -func (m *migrationUtil) OnError(data ErrorData) { - m.errorsCount++ - m.groupedErrors[data.ItemType] = append(m.groupedErrors[data.ItemType], data) - var errFormat = "[_id=%s] %s %s\n" - - if m.config.stopOnErr { - log.Printf(errFormat, data.ItemID, data.Msg, data.Error.Error()) - os.Exit(1) +func (c MigrationStats) report() { + if c.Applied == 0 && c.Fetched > 0 { + log.Printf("elapsed [%s] for [%d] items fetched with [%d] errors\n", c.Elapsed, c.Fetched, c.Errored) + return } + log.Printf("elapsed [%s] for [%d] items migrated with [%d] errors\n", c.Elapsed, c.Applied, c.Errored) } -func (m *migrationUtil) getOplogCollection() *mongo.Collection { +func (m *migrationImpl) getOplogCollection() *mongo.Collection { return m.client.Database("local").Collection("oplog.rs") } -func (m *migrationUtil) getAdminDB() *mongo.Database { +func (m *migrationImpl) getAdminDB() *mongo.Database { return m.client.Database("admin") } -func writeLastProcessed(itemID string) { - if strings.TrimSpace(itemID) != "" { - f, err := os.Create("./lastProcessedId") - if err != nil { - log.Println(err) - os.Exit(1) - } - defer f.Close() - f.WriteString(itemID) - } -} - -func (m *migrationUtil) getOplogDuration(ctx context.Context) (time.Duration, error) { +func (m *migrationImpl) getOplogDuration(ctx context.Context) (time.Duration, error) { type MongoMetaData struct { Wall time.Time `json:"wall"` } @@ -431,7 +253,7 @@ func (m *migrationUtil) getOplogDuration(ctx context.Context) (time.Duration, er return oplogDuration, nil } -func (m *migrationUtil) setWriteBatchSize(ctx context.Context) error { +func (m *migrationImpl) setWriteBatchSize(ctx context.Context) error { var calculateBatchSize = func(oplogSize int, oplogEntryBytes int, oplogMinWindow int, nopPercent int) int64 { return int64(math.Floor(float64(oplogSize) / float64(oplogEntryBytes) / float64(oplogMinWindow) / (float64(nopPercent) / 7))) } @@ -455,7 +277,7 @@ func (m *migrationUtil) setWriteBatchSize(ctx context.Context) error { return nil } -func (m *migrationUtil) checkFreeSpace(ctx context.Context, dataC *mongo.Collection) error { +func (m *migrationImpl) checkFreeSpace(ctx context.Context, dataC *mongo.Collection) error { // pass in config and mongo collection being migrated if dataC == nil { return errors.New("missing required mongo data collection") @@ -480,7 +302,7 @@ func (m *migrationUtil) checkFreeSpace(ctx context.Context, dataC *mongo.Collect return errors.New("could not get deviceData database") } -func (m *migrationUtil) getWaitTime(ctx context.Context) (float64, error) { +func (m *migrationImpl) getWaitTime(ctx context.Context) (float64, error) { type Member struct { Name string `json:"name"` Health int `json:"health"` @@ -521,7 +343,7 @@ func (m *migrationUtil) getWaitTime(ctx context.Context) (float64, error) { return 0, nil } -func (m *migrationUtil) blockUntilDBReady(ctx context.Context) error { +func (m *migrationImpl) blockUntilDBReady(ctx context.Context) error { waitTime, err := m.getWaitTime(ctx) if err != nil { return err @@ -543,56 +365,94 @@ func (m *migrationUtil) blockUntilDBReady(ctx context.Context) error { return nil } -func (m *migrationUtil) writeUpdates(ctx context.Context, dataC *mongo.Collection) error { - if dataC == nil { - return errors.New("missing required collection to write updates to") +func (m *migrationImpl) writeErrors(groupLimit *int) { + for group, errors := range m.groupedErrors { + if groupLimit != nil { + if len(errors) < *groupLimit { + continue + } + } + f, err := createFile("error", group, "%s.log") + if err != nil { + log.Println(err) + os.Exit(1) + } + defer f.Close() + for _, data := range errors { + errJSON, err := json.Marshal(data) + if err != nil { + log.Println(err) + os.Exit(1) + } + f.WriteString(string(errJSON) + "\n") + } + m.groupedErrors[group] = []ErrorData{} } - if len(m.updates) == 0 { - return nil +} + +func (m *migrationImpl) writeAudit(groupLimit *int) { + + if !m.config.dryRun { + m.groupedDiffs = map[string][]UpdateData{} + return } - var getBatches = func(chunkSize int) [][]mongo.WriteModel { - batches := [][]mongo.WriteModel{} - for i := 0; i < len(m.updates); i += chunkSize { - end := i + chunkSize - if end > len(m.updates) { - end = len(m.updates) + for group, diffs := range m.groupedDiffs { + if groupLimit != nil { + if len(diffs) < *groupLimit { + continue } - batches = append(batches, m.updates[i:end]) } - return batches - } - writtenCount := 0 - for _, batch := range getBatches(int(*m.writeBatchSize)) { - if err := m.blockUntilDBReady(ctx); err != nil { - return err + f, err := createFile("audit", group, "%s.json") + if err != nil { + log.Println(err) + os.Exit(1) } - if err := m.checkFreeSpace(ctx, dataC); err != nil { - return err + defer f.Close() + for _, data := range diffs { + diffJSON, err := json.Marshal(data) + if err != nil { + log.Println(err) + os.Exit(1) + } + f.WriteString(string(diffJSON) + "\n") } + m.groupedDiffs[group] = []UpdateData{} + } +} - if m.config.dryRun { - writtenCount += len(batch) - continue - } - results, err := dataC.BulkWrite(ctx, batch) +func writeLastProcessed(itemID string) { + if strings.TrimSpace(itemID) != "" { + f, err := os.Create("./lastProcessedId") if err != nil { - log.Printf("error writing batch updates %v", err) - return err + log.Println(err) + os.Exit(1) } + defer f.Close() + f.WriteString(itemID) + } +} - writtenCount += int(results.ModifiedCount) - writeLastProcessed(m.lastUpdatedId) +func createFile(fileType string, dataGroup string, logName string) (*os.File, error) { + var err error + if fileType == "" { + errors.Join(err, errors.New("missing file type")) } - m.updates = []mongo.WriteModel{} - m.updatedCount = m.updatedCount + writtenCount - writeLimit := 5000 - if m.config.dryRun { - log.Println("dry-run so no changes applied") - m.writeAudit(&writeLimit) - } else { - m.writeErrors(&writeLimit) - m.writeAudit(&writeLimit) + if dataGroup == "" { + errors.Join(err, errors.New("missing data group")) } - return nil + if logName == "" { + errors.Join(err, errors.New("missing log group")) + } + if err != nil { + return nil, err + } + logName = fmt.Sprintf(logName, dataGroup) + logPath := filepath.Join(".", fileType) + + err = os.MkdirAll(logPath, os.ModePerm) + if err != nil { + return nil, err + } + return os.OpenFile(logPath+"/"+logName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) } diff --git a/migrations/20231128_jellyfish_migration/utils/migration_test.go b/migrations/20231128_jellyfish_migration/utils/migration_test.go new file mode 100644 index 0000000000..100a33d3c4 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/utils/migration_test.go @@ -0,0 +1,236 @@ +package utils_test + +import ( + "context" + "crypto/sha1" + "encoding/base32" + "io" + "strings" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + + "github.com/tidepool-org/platform/data" + dataStore "github.com/tidepool-org/platform/data/store" + dataStoreMongo "github.com/tidepool-org/platform/data/store/mongo" + dataTypesBasalTest "github.com/tidepool-org/platform/data/types/basal/test" + "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" + "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" + dataTypesBloodGlucoseTest "github.com/tidepool-org/platform/data/types/blood/glucose/test" + dataTypesPumpSettingsTest "github.com/tidepool-org/platform/data/types/settings/pump/test" + "github.com/tidepool-org/platform/data/types/upload" + dataTypesUploadTest "github.com/tidepool-org/platform/data/types/upload/test" + "github.com/tidepool-org/platform/log" + logTest "github.com/tidepool-org/platform/log/test" + "github.com/tidepool-org/platform/pointer" + storeStructuredMongoTest "github.com/tidepool-org/platform/store/structured/mongo/test" + "github.com/tidepool-org/platform/test" + + "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" +) + +type fakeMigrationImpl struct { + rollback bool + rollbackSectionName string + ctx context.Context + dataC *mongo.Collection + updates []mongo.WriteModel + rawData []bson.M + errorsCount int + updatedCount int + lastUpdatedId string +} + +func newMigrationUtil(dataC *mongo.Collection, rollback bool) utils.Migration { + return &fakeMigrationImpl{ + ctx: context.Background(), + dataC: dataC, + rollback: rollback, + rollbackSectionName: "_testRollback", + updates: []mongo.WriteModel{}, + rawData: []bson.M{}, + errorsCount: 0, + updatedCount: 0, + } +} + +func (m *fakeMigrationImpl) Initialize() error { + return nil +} +func (m *fakeMigrationImpl) Execute(selector bson.M, opt *options.FindOptions, queryFn utils.MigrationQueryFn, updateFn utils.MigrationUpdateFn) error { + return nil +} +func (m *fakeMigrationImpl) OnError(data utils.ErrorData) { + m.errorsCount++ +} +func (m *fakeMigrationImpl) SetUpdates(data utils.UpdateData) { + m.updates = append(m.updates, data.GetMongoUpdates(m.rollback, m.rollbackSectionName)...) +} + +func (m *fakeMigrationImpl) GetUpdates() []mongo.WriteModel { + return m.updates +} + +func (m *fakeMigrationImpl) GetSettings() utils.Settings { + cap := 10000 + writeBatchSize := int64(1000) + return utils.Settings{ + DryRun: false, + Rollback: m.rollback, + RollbackSectionName: m.rollbackSectionName, + StopOnErr: false, + Cap: &cap, + WriteBatchSize: &writeBatchSize, + } +} + +func (m *fakeMigrationImpl) ResetUpdates() { + m.updates = []mongo.WriteModel{} +} + +func (m *fakeMigrationImpl) GetCtx() context.Context { + return context.Background() +} + +func (m *fakeMigrationImpl) GetLastID() string { + return m.lastUpdatedId +} + +func (m *fakeMigrationImpl) SetLastProcessed(lastID string) { + m.lastUpdatedId = lastID +} + +func (m *fakeMigrationImpl) GetDataCollection() *mongo.Collection { + return m.dataC +} + +func (m *fakeMigrationImpl) UpdateChecks() error { + return nil +} + +func (m *fakeMigrationImpl) SetFetched(raw []bson.M) { + m.rawData = append(m.rawData, raw...) +} + +var _ = Describe("back-37", func() { + var _ = Describe("migrationUtil", func() { + + var testData data.Data + var migration utils.Migration + + var makeJellyfishID = func(fields ...string) *string { + h := sha1.New() + hashFields := append(fields, "bootstrap") + for _, field := range hashFields { + io.WriteString(h, field) + io.WriteString(h, "_") + } + sha1 := h.Sum(nil) + id := strings.ToLower(base32.HexEncoding.WithPadding('-').EncodeToString(sha1)) + return &id + } + + var newData = func(deviceID string, requiredRecords int) data.Data { + units := pointer.FromString("mg/dL") + testData := data.Data{} + + for count := 0; count < requiredRecords; count++ { + typ := test.RandomChoice([]string{"cbg", "smbg", "basal", "pumpSettings"}) + + switch typ { + case "cbg": + datum := continuous.New() + datum.Glucose = *dataTypesBloodGlucoseTest.NewGlucose(units) + datum.Type = "cbg" + datum.Deduplicator = nil + datum.DeviceID = pointer.FromAny(deviceID) + datum.ID = makeJellyfishID(datum.Type, *datum.DeviceID, datum.Time.Format(time.RFC3339)) + testData = append(testData, datum) + case "smbg": + datum := selfmonitored.New() + datum.Glucose = *dataTypesBloodGlucoseTest.NewGlucose(units) + datum.Type = "smbg" + datum.SubType = pointer.FromString(test.RandomStringFromArray(selfmonitored.SubTypes())) + datum.Deduplicator = nil + datum.DeviceID = pointer.FromAny(deviceID) + datum.ID = makeJellyfishID(datum.Type, *datum.DeviceID, datum.Time.Format(time.RFC3339)) + testData = append(testData, datum) + case "basal": + datum := dataTypesBasalTest.RandomBasal() + datum.Deduplicator = nil + datum.DeviceID = pointer.FromAny(deviceID) + datum.ID = makeJellyfishID(datum.Type, *datum.DeviceID, datum.Time.Format(time.RFC3339)) + testData = append(testData, datum) + case "pumpSettings": + datum := dataTypesPumpSettingsTest.NewPump(units) + datum.Deduplicator = nil + datum.DeviceID = pointer.FromAny(deviceID) + datum.ID = makeJellyfishID(datum.Type, *datum.DeviceID, datum.Time.Format(time.RFC3339)) + testData = append(testData, datum) + } + + } + return testData + } + + var newDataSet = func(userID string, deviceID string) *upload.Upload { + dataSet := dataTypesUploadTest.RandomUpload() + dataSet.Active = true + dataSet.ArchivedDataSetID = nil + dataSet.ArchivedTime = nil + dataSet.CreatedTime = nil + dataSet.CreatedUserID = nil + dataSet.DeletedTime = nil + dataSet.DeletedUserID = nil + dataSet.DeviceID = pointer.FromAny(deviceID) + dataSet.Location.GPS.Origin.Time = nil + dataSet.ModifiedTime = nil + dataSet.ModifiedUserID = nil + dataSet.Origin.Time = nil + dataSet.UserID = pointer.FromAny(userID) + return dataSet + } + + var store *dataStoreMongo.Store + var repository dataStore.DataRepository + var ctx context.Context + + var collection *mongo.Collection + + BeforeEach(func() { + logger := logTest.NewLogger() + ctx = log.NewContextWithLogger(context.Background(), logger) + deviceID := "test-device-88x89" + testData = newData("test-device-88x89", 2000) + uploadDataSet := newDataSet("test-user-id", deviceID) + var err error + store, err = dataStoreMongo.NewStore(storeStructuredMongoTest.NewConfig()) + Expect(err).ToNot(HaveOccurred()) + Expect(store).ToNot(BeNil()) + collection = store.GetCollection("deviceData") + repository = store.NewDataRepository() + Expect(repository.CreateDataSetData(ctx, uploadDataSet, testData)).To(Succeed()) + }) + AfterEach(func() { + if collection != nil { + collection.Database().Drop(ctx) + } + if store != nil { + _ = store.Terminate(ctx) + } + }) + It("apply migration", func() { + migration = newMigrationUtil(collection, false) + Expect(testData).ToNot(BeNil()) + Expect(len(testData)).To(Equal(2000)) + selector, opt := utils.JellyfishUpdatesQuery(nil, nil, 50, 100) + Expect(migration.Execute(selector, opt, utils.ProcessJellyfishQueryFn, utils.WriteJellyfishUpdatesFn)).To(Succeed()) + + Expect(true).To(Equal(false)) + }) + }) +}) From c107334bac8a3ca8275438904bc4080f721b0543 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 20 Mar 2024 18:30:37 +1300 Subject: [PATCH 272/413] migration tests --- .../utils/jellyfish.go | 46 ++- .../utils/migration.go | 1 + .../utils/migrationImpl.go | 6 +- .../utils/migration_test.go | 261 +++++++++--------- .../utils/test/data.go | 149 ++++++---- .../utils/utils.go | 4 +- .../utils/utils_test.go | 10 +- 7 files changed, 276 insertions(+), 201 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/jellyfish.go b/migrations/20231128_jellyfish_migration/utils/jellyfish.go index 69f3046b09..70d9519605 100644 --- a/migrations/20231128_jellyfish_migration/utils/jellyfish.go +++ b/migrations/20231128_jellyfish_migration/utils/jellyfish.go @@ -6,6 +6,7 @@ import ( "log" "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) @@ -71,18 +72,39 @@ var ProcessJellyfishQueryFn = func(m Migration, selector bson.M, opts ...*option itemID := fmt.Sprintf("%v", item["_id"]) userID := fmt.Sprintf("%v", item["_userId"]) itemType := fmt.Sprintf("%v", item["type"]) - updates, revert, err := ProcessDatum(itemID, itemType, item) - if err != nil { - m.OnError(ErrorData{Error: err, ItemID: itemID, ItemType: itemType}) - } else if len(updates) > 0 { - m.SetUpdates(UpdateData{ - Filter: bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}, - ItemID: itemID, - UserID: userID, - ItemType: itemType, - Apply: updates, - Revert: revert, - }) + if m.GetSettings().Rollback { + if rollback, ok := item[m.GetSettings().RollbackSectionName].(primitive.A); ok { + cmds := []bson.M{} + for _, cmd := range rollback { + if cmd, ok := cmd.(bson.M); ok { + cmds = append(cmds, cmd) + } + } + if len(cmds) > 0 { + m.SetUpdates(UpdateData{ + Filter: bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}, + ItemID: itemID, + UserID: userID, + ItemType: itemType, + Apply: cmds, + }) + } + } + + } else { + updates, revert, err := ProcessDatum(itemID, itemType, item) + if err != nil { + m.OnError(ErrorData{Error: err, ItemID: itemID, ItemType: itemType}) + } else if len(updates) > 0 { + m.SetUpdates(UpdateData{ + Filter: bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}, + ItemID: itemID, + UserID: userID, + ItemType: itemType, + Apply: updates, + Revert: revert, + }) + } } m.SetLastProcessed(itemID) all = append(all, item) diff --git a/migrations/20231128_jellyfish_migration/utils/migration.go b/migrations/20231128_jellyfish_migration/utils/migration.go index d36edad323..caab53f0ab 100644 --- a/migrations/20231128_jellyfish_migration/utils/migration.go +++ b/migrations/20231128_jellyfish_migration/utils/migration.go @@ -53,6 +53,7 @@ type Migration interface { ResetUpdates() SetLastProcessed(lastID string) SetFetched(raw []bson.M) + GetStats() MigrationStats } type Settings struct { diff --git a/migrations/20231128_jellyfish_migration/utils/migrationImpl.go b/migrations/20231128_jellyfish_migration/utils/migrationImpl.go index 3abcbb53ea..08f332f428 100644 --- a/migrations/20231128_jellyfish_migration/utils/migrationImpl.go +++ b/migrations/20231128_jellyfish_migration/utils/migrationImpl.go @@ -112,7 +112,7 @@ func (m *migrationImpl) Execute( break } } - m.getStats().report() + m.GetStats().report() m.writeErrors(nil) m.writeAudit(nil) return nil @@ -159,7 +159,7 @@ func (m *migrationImpl) SetFetched(raw []bson.M) { m.rawData = append(m.rawData, raw...) } -func (m *migrationImpl) getStats() MigrationStats { +func (m *migrationImpl) GetStats() MigrationStats { return MigrationStats{ Errored: m.errorsCount, Fetched: len(m.rawData), @@ -196,7 +196,7 @@ func (m *migrationImpl) UpdateChecks() error { func (m *migrationImpl) capReached() bool { if m.config.cap != nil { - stats := m.getStats() + stats := m.GetStats() percent := (float64(stats.Fetched) * float64(100)) / float64(*m.config.cap) log.Printf("processed %.0f %% of %d records and applied %d changes", percent, *m.config.cap, stats.Applied) diff --git a/migrations/20231128_jellyfish_migration/utils/migration_test.go b/migrations/20231128_jellyfish_migration/utils/migration_test.go index 100a33d3c4..5e31d89171 100644 --- a/migrations/20231128_jellyfish_migration/utils/migration_test.go +++ b/migrations/20231128_jellyfish_migration/utils/migration_test.go @@ -2,11 +2,6 @@ package utils_test import ( "context" - "crypto/sha1" - "encoding/base32" - "io" - "strings" - "time" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -14,26 +9,15 @@ import ( "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" - "github.com/tidepool-org/platform/data" - dataStore "github.com/tidepool-org/platform/data/store" dataStoreMongo "github.com/tidepool-org/platform/data/store/mongo" - dataTypesBasalTest "github.com/tidepool-org/platform/data/types/basal/test" - "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" - "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" - dataTypesBloodGlucoseTest "github.com/tidepool-org/platform/data/types/blood/glucose/test" - dataTypesPumpSettingsTest "github.com/tidepool-org/platform/data/types/settings/pump/test" - "github.com/tidepool-org/platform/data/types/upload" - dataTypesUploadTest "github.com/tidepool-org/platform/data/types/upload/test" - "github.com/tidepool-org/platform/log" + platformLog "github.com/tidepool-org/platform/log" logTest "github.com/tidepool-org/platform/log/test" - "github.com/tidepool-org/platform/pointer" - storeStructuredMongoTest "github.com/tidepool-org/platform/store/structured/mongo/test" - "github.com/tidepool-org/platform/test" - "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" + "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils/test" + storeStructuredMongoTest "github.com/tidepool-org/platform/store/structured/mongo/test" ) -type fakeMigrationImpl struct { +type fakeMigrator struct { rollback bool rollbackSectionName string ctx context.Context @@ -46,7 +30,7 @@ type fakeMigrationImpl struct { } func newMigrationUtil(dataC *mongo.Collection, rollback bool) utils.Migration { - return &fakeMigrationImpl{ + return &fakeMigrator{ ctx: context.Background(), dataC: dataC, rollback: rollback, @@ -58,179 +42,200 @@ func newMigrationUtil(dataC *mongo.Collection, rollback bool) utils.Migration { } } -func (m *fakeMigrationImpl) Initialize() error { +func (m *fakeMigrator) Initialize() error { return nil } -func (m *fakeMigrationImpl) Execute(selector bson.M, opt *options.FindOptions, queryFn utils.MigrationQueryFn, updateFn utils.MigrationUpdateFn) error { +func (m *fakeMigrator) Execute(selector bson.M, selectorOpt *options.FindOptions, queryFn utils.MigrationQueryFn, updateFn utils.MigrationUpdateFn) error { + settings := m.GetSettings() + for queryFn(m, selector, selectorOpt) { + updated, err := updateFn(m) + if err != nil { + return err + } + m.updatedCount += updated + if settings.Cap != nil { + if m.GetStats().Fetched >= *settings.Cap { + break + } + } + } return nil } -func (m *fakeMigrationImpl) OnError(data utils.ErrorData) { +func (m *fakeMigrator) OnError(data utils.ErrorData) { m.errorsCount++ } -func (m *fakeMigrationImpl) SetUpdates(data utils.UpdateData) { +func (m *fakeMigrator) SetUpdates(data utils.UpdateData) { m.updates = append(m.updates, data.GetMongoUpdates(m.rollback, m.rollbackSectionName)...) } - -func (m *fakeMigrationImpl) GetUpdates() []mongo.WriteModel { +func (m *fakeMigrator) GetUpdates() []mongo.WriteModel { return m.updates } -func (m *fakeMigrationImpl) GetSettings() utils.Settings { - cap := 10000 - writeBatchSize := int64(1000) +func (m *fakeMigrator) GetSettings() utils.Settings { + writeBatchSize := int64(20) return utils.Settings{ DryRun: false, Rollback: m.rollback, RollbackSectionName: m.rollbackSectionName, StopOnErr: false, - Cap: &cap, + Cap: nil, WriteBatchSize: &writeBatchSize, } } -func (m *fakeMigrationImpl) ResetUpdates() { +func (m *fakeMigrator) ResetUpdates() { m.updates = []mongo.WriteModel{} } -func (m *fakeMigrationImpl) GetCtx() context.Context { +func (m *fakeMigrator) GetCtx() context.Context { return context.Background() } -func (m *fakeMigrationImpl) GetLastID() string { +func (m *fakeMigrator) GetLastID() string { return m.lastUpdatedId } -func (m *fakeMigrationImpl) SetLastProcessed(lastID string) { +func (m *fakeMigrator) SetLastProcessed(lastID string) { m.lastUpdatedId = lastID } -func (m *fakeMigrationImpl) GetDataCollection() *mongo.Collection { +func (m *fakeMigrator) GetDataCollection() *mongo.Collection { return m.dataC } -func (m *fakeMigrationImpl) UpdateChecks() error { +func (m *fakeMigrator) UpdateChecks() error { return nil } -func (m *fakeMigrationImpl) SetFetched(raw []bson.M) { +func (m *fakeMigrator) SetFetched(raw []bson.M) { m.rawData = append(m.rawData, raw...) } +func (m *fakeMigrator) GetStats() utils.MigrationStats { + return utils.MigrationStats{ + Errored: m.errorsCount, + Fetched: len(m.rawData), + Applied: m.updatedCount, + } +} + +func setCollectionData(ctx context.Context, dataC *mongo.Collection, dataSetData []map[string]interface{}) error { + insertData := make([]mongo.WriteModel, 0, len(dataSetData)) + for _, datum := range dataSetData { + insertData = append(insertData, mongo.NewInsertOneModel().SetDocument(datum)) + } + opts := options.BulkWrite().SetOrdered(false) + _, err := dataC.BulkWrite(ctx, insertData, opts) + return err +} + var _ = Describe("back-37", func() { var _ = Describe("migrationUtil", func() { - var testData data.Data + var testData []map[string]interface{} var migration utils.Migration - - var makeJellyfishID = func(fields ...string) *string { - h := sha1.New() - hashFields := append(fields, "bootstrap") - for _, field := range hashFields { - io.WriteString(h, field) - io.WriteString(h, "_") - } - sha1 := h.Sum(nil) - id := strings.ToLower(base32.HexEncoding.WithPadding('-').EncodeToString(sha1)) - return &id - } - - var newData = func(deviceID string, requiredRecords int) data.Data { - units := pointer.FromString("mg/dL") - testData := data.Data{} - - for count := 0; count < requiredRecords; count++ { - typ := test.RandomChoice([]string{"cbg", "smbg", "basal", "pumpSettings"}) - - switch typ { - case "cbg": - datum := continuous.New() - datum.Glucose = *dataTypesBloodGlucoseTest.NewGlucose(units) - datum.Type = "cbg" - datum.Deduplicator = nil - datum.DeviceID = pointer.FromAny(deviceID) - datum.ID = makeJellyfishID(datum.Type, *datum.DeviceID, datum.Time.Format(time.RFC3339)) - testData = append(testData, datum) - case "smbg": - datum := selfmonitored.New() - datum.Glucose = *dataTypesBloodGlucoseTest.NewGlucose(units) - datum.Type = "smbg" - datum.SubType = pointer.FromString(test.RandomStringFromArray(selfmonitored.SubTypes())) - datum.Deduplicator = nil - datum.DeviceID = pointer.FromAny(deviceID) - datum.ID = makeJellyfishID(datum.Type, *datum.DeviceID, datum.Time.Format(time.RFC3339)) - testData = append(testData, datum) - case "basal": - datum := dataTypesBasalTest.RandomBasal() - datum.Deduplicator = nil - datum.DeviceID = pointer.FromAny(deviceID) - datum.ID = makeJellyfishID(datum.Type, *datum.DeviceID, datum.Time.Format(time.RFC3339)) - testData = append(testData, datum) - case "pumpSettings": - datum := dataTypesPumpSettingsTest.NewPump(units) - datum.Deduplicator = nil - datum.DeviceID = pointer.FromAny(deviceID) - datum.ID = makeJellyfishID(datum.Type, *datum.DeviceID, datum.Time.Format(time.RFC3339)) - testData = append(testData, datum) - } - - } - return testData - } - - var newDataSet = func(userID string, deviceID string) *upload.Upload { - dataSet := dataTypesUploadTest.RandomUpload() - dataSet.Active = true - dataSet.ArchivedDataSetID = nil - dataSet.ArchivedTime = nil - dataSet.CreatedTime = nil - dataSet.CreatedUserID = nil - dataSet.DeletedTime = nil - dataSet.DeletedUserID = nil - dataSet.DeviceID = pointer.FromAny(deviceID) - dataSet.Location.GPS.Origin.Time = nil - dataSet.ModifiedTime = nil - dataSet.ModifiedUserID = nil - dataSet.Origin.Time = nil - dataSet.UserID = pointer.FromAny(userID) - return dataSet - } - + const datumCount = 50 var store *dataStoreMongo.Store - var repository dataStore.DataRepository var ctx context.Context - var collection *mongo.Collection - BeforeEach(func() { logger := logTest.NewLogger() - ctx = log.NewContextWithLogger(context.Background(), logger) - deviceID := "test-device-88x89" - testData = newData("test-device-88x89", 2000) - uploadDataSet := newDataSet("test-user-id", deviceID) + ctx = platformLog.NewContextWithLogger(context.Background(), logger) + testData = test.BulkJellyfishData("test-device-88x89", "test-group-id", "test-user-id-123", datumCount) var err error store, err = dataStoreMongo.NewStore(storeStructuredMongoTest.NewConfig()) Expect(err).ToNot(HaveOccurred()) Expect(store).ToNot(BeNil()) - collection = store.GetCollection("deviceData") - repository = store.NewDataRepository() - Expect(repository.CreateDataSetData(ctx, uploadDataSet, testData)).To(Succeed()) }) AfterEach(func() { - if collection != nil { - collection.Database().Drop(ctx) - } if store != nil { _ = store.Terminate(ctx) } }) It("apply migration", func() { + collection := store.GetCollection("testMigration") + Expect(setCollectionData(ctx, collection, testData)).To(Succeed()) + + migration = newMigrationUtil(collection, false) + Expect(testData).ToNot(BeNil()) + Expect(len(testData)).To(Equal(datumCount)) + allDocs, err := collection.CountDocuments(ctx, bson.D{}) + Expect(err).To(BeNil()) + Expect(allDocs).To(Equal(int64(datumCount))) + selector, opt := utils.JellyfishUpdatesQuery(nil, nil, 50, 100) + Expect(migration.Execute(selector, opt, utils.ProcessJellyfishQueryFn, utils.WriteJellyfishUpdatesFn)).To(Succeed()) + stats := migration.GetStats() + Expect(stats.Errored).To(Equal(0)) + Expect(stats.Fetched).To(Equal(datumCount)) + Expect(stats.Applied).To(Equal(datumCount * 3)) + + cur, err := collection.Find(ctx, bson.D{}) + Expect(err).To(BeNil()) + migrated := []map[string]interface{}{} + cur.All(ctx, &migrated) + + Expect(len(migrated)).To(Equal(datumCount)) + + for _, item := range migrated { + Expect(item).Should(HaveKey("_deduplicator")) + Expect(item).Should(HaveKey(migration.GetSettings().RollbackSectionName)) + Expect(item).ShouldNot(HaveKey("localTime")) + } + + }) + + It("apply then rollback migration will return the data to its orginal state", func() { + + collection := store.GetCollection("testRollback") + Expect(setCollectionData(ctx, collection, testData)).To(Succeed()) + + findOptions := options.Find() + findOptions.SetSort(bson.D{{Key: "_id", Value: -1}}) + migration = newMigrationUtil(collection, false) Expect(testData).ToNot(BeNil()) - Expect(len(testData)).To(Equal(2000)) + Expect(len(testData)).To(Equal(datumCount)) + + cur, err := collection.Find(ctx, bson.D{}, findOptions) + Expect(err).To(BeNil()) + + original := []map[string]interface{}{} + cur.All(ctx, &original) + Expect(len(original)).To(Equal(datumCount)) + selector, opt := utils.JellyfishUpdatesQuery(nil, nil, 50, 100) Expect(migration.Execute(selector, opt, utils.ProcessJellyfishQueryFn, utils.WriteJellyfishUpdatesFn)).To(Succeed()) - Expect(true).To(Equal(false)) + cur, err = collection.Find(ctx, bson.D{}, findOptions) + Expect(err).To(BeNil()) + migrated := []map[string]interface{}{} + cur.All(ctx, &migrated) + Expect(len(migrated)).To(Equal(datumCount)) + + rollback := newMigrationUtil(collection, true) + + rollbackSelector, rollbackOpt := utils.JellyfishRollbackQuery(rollback.GetSettings().RollbackSectionName, nil, nil, 50, 100) + Expect(rollback.Execute(rollbackSelector, rollbackOpt, utils.ProcessJellyfishQueryFn, utils.WriteJellyfishUpdatesFn)).To(Succeed()) + + cur, err = collection.Find(ctx, bson.D{}, findOptions) + Expect(err).To(BeNil()) + rolledback := []map[string]interface{}{} + cur.All(ctx, &rolledback) + Expect(len(rolledback)).To(Equal(datumCount)) + + for i, item := range rolledback { + Expect(original[i]["_id"]).To(Equal(item["_id"])) + Expect(migrated[i]["_id"]).To(Equal(item["_id"])) + + Expect(migrated[i]).Should(HaveKey("_deduplicator")) + Expect(original[i]).ShouldNot(HaveKey("_deduplicator")) + Expect(item).ShouldNot(HaveKey("_deduplicator")) + + Expect(migrated[i]).Should(HaveKey((migration.GetSettings().RollbackSectionName))) + Expect(original[i]).ShouldNot(HaveKey((migration.GetSettings().RollbackSectionName))) + Expect(item).ShouldNot(HaveKey((migration.GetSettings().RollbackSectionName))) + } + }) }) }) diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go index a40d63a397..805c467d04 100644 --- a/migrations/20231128_jellyfish_migration/utils/test/data.go +++ b/migrations/20231128_jellyfish_migration/utils/test/data.go @@ -1,8 +1,15 @@ package test import ( + "crypto/sha1" + "encoding/base32" + "io" + "strings" + "time" + "github.com/tidepool-org/platform/data/types/settings/pump" pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" + "github.com/tidepool-org/platform/test" ) func base(deviceID string) map[string]interface{} { @@ -12,8 +19,8 @@ func base(deviceID string) map[string]interface{} { "deviceTime": "2017-11-05T12:56:51", "id": "3f0075ad57ad603c83dc1e1a76aefcaf", "localTime": "2017-11-05T12:56:51.000Z", - "_userId": "87df73fd41", - "_groupId": "8da6e693b8", + "_userId": "8da6e693b8", + "_groupId": "87df73fd41", "createdTime": "2022-06-21T22:40:07.732+00:00", "_version": 0, "_active": true, @@ -22,9 +29,26 @@ func base(deviceID string) map[string]interface{} { } } +func baseWithTime(deviceID string, groupID string, userID string, t time.Time) map[string]interface{} { + now := time.Now() + return map[string]interface{}{ + "_id": "17dbokav5t6pssjv72gm0nie3u25b54m", + "deviceId": deviceID, + "deviceTime": t.Format("2006-01-02T15:04:05"), + "id": "3f0075ad57ad603c83dc1e1a76aefcaf", + "localTime": t.Format("2006-01-02T15:04:05.999Z"), + "_userId": userID, + "_groupId": groupID, + "createdTime": now.Format("2006-01-02T15:04:05.999+07:00"), + "_version": 0, + "_active": true, + "uploadId": "a21c82a5f5d2860add2539acded6b614", + "time": t.Format("2006-01-02T15:04:05.999+07:00"), + } +} + // payload as a string rather than object or array -func dexG5MobDatumStringPayload() map[string]interface{} { - datum := base("DexG5Mob_iPhone") +func dexG5MobDatumStringPayload(datum map[string]interface{}) map[string]interface{} { datum["payload"] = `{"systemTime":"2017-11-05T18:56:51Z","transmitterId":"410X6M","transmitterTicks":5796922,"trend":"flat","trendRate":0.6,"trendRateUnits":"mg/dL/min"}` datum["type"] = "cbg" datum["units"] = "mmol/L" @@ -32,8 +56,7 @@ func dexG5MobDatumStringPayload() map[string]interface{} { return datum } -func dexG5MobDatumStringAnnotations() map[string]interface{} { - datum := base("DexG5Mob_iPhone") +func dexG5MobDatumStringAnnotations(datum map[string]interface{}) map[string]interface{} { datum["annotations"] = `[{"code":"bg/out-of-range","threshold":40,"value":"low"}]` datum["type"] = "cbg" datum["units"] = "mmol/L" @@ -41,9 +64,7 @@ func dexG5MobDatumStringAnnotations() map[string]interface{} { return datum } -func tandemPumpSettingsDatum() map[string]interface{} { - datum := base("tandem99999999") - +func tandemPumpSettingsDatum(datum map[string]interface{}) map[string]interface{} { datum["type"] = "pumpSettings" datum["activeSchedule"] = "Simple" datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mg/dL"} @@ -96,9 +117,7 @@ func tandemPumpSettingsDatum() map[string]interface{} { return datum } -func tandemPumpSettingsWithSleepScheduleDatum() map[string]interface{} { - datum := base("tandem99999999") - +func tandemPumpSettingsWithSleepScheduleDatum(datum map[string]interface{}) map[string]interface{} { datum["type"] = "pumpSettings" datum["activeSchedule"] = "Simple" datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mg/dL"} @@ -158,9 +177,7 @@ func tandemPumpSettingsWithSleepScheduleDatum() map[string]interface{} { return datum } -func carelinkPumpSettings() map[string]interface{} { - datum := base("MiniMed 530G - 751-=-11111111") - +func carelinkPumpSettings(datum map[string]interface{}) map[string]interface{} { datum["type"] = "pumpSettings" datum["activeSchedule"] = "standard" datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mg/dL"} @@ -195,9 +212,7 @@ func carelinkPumpSettings() map[string]interface{} { return datum } -func omnipodPumpSettingsDatum() map[string]interface{} { - - datum := base("InsOmn-837268") +func omnipodPumpSettingsDatum(datum map[string]interface{}) map[string]interface{} { datum["type"] = "pumpSettings" datum["activeSchedule"] = "Mine-2016" datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mg/dL"} @@ -228,9 +243,7 @@ func omnipodPumpSettingsDatum() map[string]interface{} { return datum } -func omnipodPumpSettingsDatumTargetSet() map[string]interface{} { - - datum := base("InsOmn-837268") +func omnipodPumpSettingsDatumTargetSet(datum map[string]interface{}) map[string]interface{} { datum["type"] = "pumpSettings" datum["activeSchedule"] = "Mine-2016" datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mg/dL"} @@ -261,8 +274,7 @@ func omnipodPumpSettingsDatumTargetSet() map[string]interface{} { return datum } -func tandemAutomatedBasalDatum() map[string]interface{} { - datum := base("tandemCIQ1111111111111") +func tandemAutomatedBasalDatum(datum map[string]interface{}) map[string]interface{} { datum["type"] = "basal" datum["deliveryType"] = "automated" datum["timezoneOffset"] = -300 @@ -280,8 +292,7 @@ func tandemAutomatedBasalDatum() map[string]interface{} { return datum } -func tandemWizardDatum() map[string]interface{} { - datum := base("tandemCIQ1111111111111") +func tandemWizardDatum(datum map[string]interface{}) map[string]interface{} { datum["type"] = "wizard" datum["timezoneOffset"] = -300 @@ -309,16 +320,14 @@ func tandemWizardDatum() map[string]interface{} { return datum } -func reservoirChangeDeviceEventDatum() map[string]interface{} { - datum := base("InsOmn-1111111111111") +func reservoirChangeDeviceEventDatum(datum map[string]interface{}) map[string]interface{} { datum["type"] = "deviceEvent" datum["subType"] = "reservoirChange" datum["status"] = "cvv61jde62b6i28bgot57f18bor5au1n" return datum } -func alarmDeviceEventDatum() map[string]interface{} { - datum := base("tandemCIQ100000000000") +func alarmDeviceEventDatum(datum map[string]interface{}) map[string]interface{} { datum["type"] = "deviceEvent" datum["subType"] = "status" datum["status"] = "suspended" @@ -329,8 +338,7 @@ func alarmDeviceEventDatum() map[string]interface{} { return datum } -func cgmSettingsDatum() map[string]interface{} { - datum := base("DexG5MobRec-1111111111111") +func cgmSettingsDatum(datum map[string]interface{}) map[string]interface{} { datum["type"] = "cgmSettings" datum["units"] = "mmol/L" @@ -364,8 +372,7 @@ func cgmSettingsDatum() map[string]interface{} { return datum } -func emptyPayload() map[string]interface{} { - datum := base("Dex-device") +func emptyPayload(datum map[string]interface{}) map[string]interface{} { datum["payload"] = map[string]interface{}{} datum["type"] = "cbg" datum["units"] = "mmol/L" @@ -373,28 +380,68 @@ func emptyPayload() map[string]interface{} { return datum } -func pumpSettingsWithBolus() map[string]interface{} { - datum := tandemPumpSettingsDatum() - +func pumpSettingsWithBolus(datum map[string]interface{}) map[string]interface{} { + datum = tandemPumpSettingsDatum(datum) datum["bolus"] = &pump.BolusMap{ "bolus-1": pumpTest.NewRandomBolus(), "bolus-2": pumpTest.NewRandomBolus(), } - return datum } -var CBGDexcomG5StringPayloadDatum = dexG5MobDatumStringPayload() -var CBGDexcomG5StringAnnotationsDatum = dexG5MobDatumStringAnnotations() -var PumpSettingsTandem = tandemPumpSettingsDatum() -var PumpSettingsWithSleepScheduleTandem = tandemPumpSettingsWithSleepScheduleDatum() -var PumpSettingsCarelink = carelinkPumpSettings() -var PumpSettingsOmnipod = omnipodPumpSettingsDatum() -var PumpSettingsOmnipodBGTargetCorrect = omnipodPumpSettingsDatumTargetSet() -var AutomatedBasalTandem = tandemAutomatedBasalDatum() -var WizardTandem = tandemWizardDatum() -var ReservoirChangeWithStatus = reservoirChangeDeviceEventDatum() -var AlarmDeviceEventDatum = alarmDeviceEventDatum() -var CGMSetting = cgmSettingsDatum() -var EmptyPayloadDatum = emptyPayload() -var PumpSettingsWithBolusDatum = pumpSettingsWithBolus() +var CBGDexcomG5StringPayloadDatum = dexG5MobDatumStringPayload(base("DexG5Mob_iPhone")) +var CBGDexcomG5StringAnnotationsDatum = dexG5MobDatumStringAnnotations(base("DexG5Mob_iPhone")) +var PumpSettingsTandem = tandemPumpSettingsDatum(base("tandem99999999")) +var PumpSettingsWithSleepScheduleTandem = tandemPumpSettingsWithSleepScheduleDatum(base("tandem99999999")) +var PumpSettingsCarelink = carelinkPumpSettings(base("MiniMed 530G - 751-=-11111111")) +var PumpSettingsOmnipod = omnipodPumpSettingsDatum(base("InsOmn-837268")) +var PumpSettingsOmnipodBGTargetCorrect = omnipodPumpSettingsDatumTargetSet(base("InsOmn-837268")) +var AutomatedBasalTandem = tandemAutomatedBasalDatum(base("tandemCIQ1111111111111")) +var WizardTandem = tandemWizardDatum(base("tandemCIQ1111111111111")) +var ReservoirChangeWithStatus = reservoirChangeDeviceEventDatum(base("InsOmn-1111111111111")) +var AlarmDeviceEventDatum = alarmDeviceEventDatum(base("tandemCIQ100000000000")) +var CGMSetting = cgmSettingsDatum(base("DexG5MobRec-1111111111111")) +var EmptyPayloadDatum = emptyPayload(base("Dex-device")) +var PumpSettingsWithBolusDatum = pumpSettingsWithBolus(base("tandem99999999")) + +func BulkJellyfishData(deviceID string, groupID string, userID string, requiredRecords int) []map[string]interface{} { + data := []map[string]interface{}{} + twoWeeksAgo := time.Now().AddDate(0, 0, 14) + + var makeJellyfishID = func(fields []string) string { + h := sha1.New() + hashFields := append(fields, "bootstrap") + for _, field := range hashFields { + io.WriteString(h, field) + io.WriteString(h, "_") + } + sha1 := h.Sum(nil) + id := strings.ToLower(base32.HexEncoding.WithPadding('-').EncodeToString(sha1)) + return id + } + + for count := 0; count < requiredRecords; count++ { + typ := test.RandomChoice([]string{"cbg", "wizard", "deviceEvent"}) + dTime := twoWeeksAgo.Add(time.Duration(count) * time.Minute) + base := baseWithTime(deviceID, groupID, userID, dTime) + var datum map[string]interface{} + + switch typ { + case "cbg": + datum = dexG5MobDatumStringPayload(base) + case "cgmSettings": + datum = cgmSettingsDatum(base) + case "pumpSettings": + datum = omnipodPumpSettingsDatumTargetSet(base) + case "wizard": + datum = tandemWizardDatum(base) + case "deviceEvent": + datum = alarmDeviceEventDatum(base) + } + datum["_id"] = makeJellyfishID([]string{userID, deviceID, dTime.Format(time.RFC3339), typ}) + datum["id"] = datum["_id"] + data = append(data, datum) + } + + return data +} diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 297d63e046..d9b136e7d7 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -95,7 +95,6 @@ func updateTragetPrecision(targetObj map[string]interface{}) map[string]interfac } func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[string]interface{}, error) { - updatedObject := map[string]interface{}{} err := deepCopy(incomingObject, updatedObject) if err != nil { @@ -162,7 +161,7 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s } } if overridePresets := updatedObject["overridePresets"]; overridePresets != nil { - log.Printf("## TODO [%s] [%s] overridePresets %#v", b.datumType, b.datumID, overridePresets) + log.Printf("## TODO [%s] [%s] overridePresets", b.datumType, b.datumID) } case selfmonitored.Type, ketone.Type, continuous.Type: @@ -464,6 +463,7 @@ func ProcessDatum(dataID string, dataType string, bsonData bson.M) ([]bson.M, [] } apply, revert, err := b.datumChanges(storedData) + if err != nil { return nil, nil, err } diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 7457c39388..d63696c519 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -43,7 +43,7 @@ var _ = Describe("back-37", func() { applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.AutomatedBasalTandem)) - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "CFDp66+LJvYW7rxf+4ndFd8hoTMq+ymzwLnuEUEqhVs="})) + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "YOItOWBgIIoEkqVsBq9yrOZ5utmsKTIezszpGBj5Vpc="})) Expect(applyUnset).Should(HaveKeyWithValue("percent", "")) Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) Expect(revertSet).Should(HaveKeyWithValue("percent", float64(0.47857142857142865))) @@ -53,7 +53,7 @@ var _ = Describe("back-37", func() { applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.PumpSettingsTandem)) - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "bpKLJbi5JfqD7N0WJ1vj0ck03c9EZ3U0H09TCLhdd3k="})) + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "l5e6HoVqMu3ZOUjqaky/m6ZNw+D0UFxbYw/fM9P4PXc="})) Expect(applySet).Should(HaveKeyWithValue("bgTargets.Simple.0.target", 5.55075)) Expect(applySet).Should(HaveKeyWithValue("bgTargets.Simple.1.target", 5.55075)) Expect(applySet).Should(HaveKeyWithValue("bgTargets.Standard.0.target", 5.55075)) @@ -73,7 +73,7 @@ var _ = Describe("back-37", func() { applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.PumpSettingsWithSleepScheduleTandem)) - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "bpKLJbi5JfqD7N0WJ1vj0ck03c9EZ3U0H09TCLhdd3k="})) + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "l5e6HoVqMu3ZOUjqaky/m6ZNw+D0UFxbYw/fM9P4PXc="})) Expect(applySet).Should(HaveKey("sleepSchedules")) applyObj := applySet.(primitive.M) @@ -126,7 +126,7 @@ var _ = Describe("back-37", func() { applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.WizardTandem)) - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "o6ybZQtDZ95FvuV0zYGphri2SIGesbLCbkHxc1wbbEE="})) + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "orP5cbifS8h0f3HWZcTOIf4B431HO1OReg9o1nmFnU4="})) Expect(applySet).Should(HaveKeyWithValue("bgInput", 4.4406)) Expect(applySet).Should(HaveKeyWithValue("bgTarget.target", 4.4406)) Expect(applyUnset).Should(HaveKeyWithValue("localTime", "")) @@ -140,7 +140,7 @@ var _ = Describe("back-37", func() { applySet, _, revertUnset, revertSet := setup(getBSONData(test.PumpSettingsCarelink)) - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "NC17pw1UAaab50iChhQXJ+N9dTi6GduTy9UjsMHolow="})) + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "LgRaGs4QkIBV9sHUjurpMt/ALU+7F7ZlU8xNxhkTQwQ="})) Expect(applySet).Should(HaveKeyWithValue("bgTarget.0.target", 5.55075)) Expect(applySet).Should(HaveKeyWithValue("bgTarget.1.target", 5.55075)) Expect(applySet).Should(HaveKeyWithValue("units.bg", "mmol/L")) From eef58bdb63294a65ea8fe6cf4ef6c477b1e4550a Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 21 Mar 2024 11:51:32 +1300 Subject: [PATCH 273/413] tests compare original vs rolledback item --- .../utils/migration_test.go | 18 +++++------------- .../utils/test/data.go | 3 +-- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/migration_test.go b/migrations/20231128_jellyfish_migration/utils/migration_test.go index 5e31d89171..e6430e2896 100644 --- a/migrations/20231128_jellyfish_migration/utils/migration_test.go +++ b/migrations/20231128_jellyfish_migration/utils/migration_test.go @@ -134,7 +134,7 @@ var _ = Describe("back-37", func() { var testData []map[string]interface{} var migration utils.Migration - const datumCount = 50 + const datumCount = 1000 var store *dataStoreMongo.Store var ctx context.Context @@ -152,7 +152,7 @@ var _ = Describe("back-37", func() { _ = store.Terminate(ctx) } }) - It("apply migration", func() { + It("apply migration will set _deduplicator and also rollback data", func() { collection := store.GetCollection("testMigration") Expect(setCollectionData(ctx, collection, testData)).To(Succeed()) @@ -223,17 +223,9 @@ var _ = Describe("back-37", func() { cur.All(ctx, &rolledback) Expect(len(rolledback)).To(Equal(datumCount)) - for i, item := range rolledback { - Expect(original[i]["_id"]).To(Equal(item["_id"])) - Expect(migrated[i]["_id"]).To(Equal(item["_id"])) - - Expect(migrated[i]).Should(HaveKey("_deduplicator")) - Expect(original[i]).ShouldNot(HaveKey("_deduplicator")) - Expect(item).ShouldNot(HaveKey("_deduplicator")) - - Expect(migrated[i]).Should(HaveKey((migration.GetSettings().RollbackSectionName))) - Expect(original[i]).ShouldNot(HaveKey((migration.GetSettings().RollbackSectionName))) - Expect(item).ShouldNot(HaveKey((migration.GetSettings().RollbackSectionName))) + for i, rollbackItem := range rolledback { + Expect(migrated[i]["_id"]).To(Equal(rollbackItem["_id"])) + Expect(original[i]).To(Equal(rollbackItem)) } }) diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go index 805c467d04..d78e2b2b79 100644 --- a/migrations/20231128_jellyfish_migration/utils/test/data.go +++ b/migrations/20231128_jellyfish_migration/utils/test/data.go @@ -311,7 +311,7 @@ func tandemWizardDatum(datum map[string]interface{}) map[string]interface{} { } datum["units"] = "mmol/L" - datum["duration"] = 300000 + datum["duration"] = float64(300000) datum["rate"] = 0.335 datum["percent"] = 0.47857142857142865 datum["conversionOffset"] = 0 @@ -442,6 +442,5 @@ func BulkJellyfishData(deviceID string, groupID string, userID string, requiredR datum["id"] = datum["_id"] data = append(data, datum) } - return data } From e85a44761b62f581f6001f81ddcbfcfd0f6cd25d Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 21 Mar 2024 15:07:51 +1300 Subject: [PATCH 274/413] move out mongo instance checker for easier testing --- .../jellyfish_migration.go | 24 +- .../utils/data_migration.go | 413 ++++++++++++++++ ...gration_test.go => data_migration_test.go} | 142 ++---- .../utils/{jellyfish.go => jellyfish_data.go} | 8 +- .../utils/migration.go | 156 ------ .../utils/migrationImpl.go | 458 ------------------ .../utils/mongo_instance_check.go | 229 +++++++++ .../utils/utils.go | 1 - 8 files changed, 705 insertions(+), 726 deletions(-) create mode 100644 migrations/20231128_jellyfish_migration/utils/data_migration.go rename migrations/20231128_jellyfish_migration/utils/{migration_test.go => data_migration_test.go} (55%) rename migrations/20231128_jellyfish_migration/utils/{jellyfish.go => jellyfish_data.go} (89%) delete mode 100644 migrations/20231128_jellyfish_migration/utils/migration.go delete mode 100644 migrations/20231128_jellyfish_migration/utils/migrationImpl.go create mode 100644 migrations/20231128_jellyfish_migration/utils/mongo_instance_check.go diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 154ea70454..b02d8f2d21 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -12,6 +12,7 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" + "github.com/tidepool-org/platform/pointer" ) type Migration struct { @@ -19,7 +20,7 @@ type Migration struct { cli *cli.App config *config client *mongo.Client - migrationUtil utils.Migration + migrationUtil *utils.DataMigration } type config struct { @@ -70,16 +71,23 @@ func (m *Migration) RunAndExit() { return fmt.Errorf("unable to connect to MongoDB: %w", err) } defer m.client.Disconnect(m.ctx) + + dbChecker := utils.NewMongoInstanceCheck( + m.client, + utils.NewMongoInstanceCheckConfig(&m.config.nopPercent), + ) + m.migrationUtil, err = utils.NewMigration( m.ctx, - utils.NewMigrationConfig( + utils.NewDataMigrationConfig( &m.config.dryRun, &m.config.stopOnErr, &m.config.rollback, &m.config.rollbackSectionName, - &m.config.nopPercent, - &m.config.cap), - m.client, + &m.config.cap, + pointer.FromBool(true), + ), + dbChecker, m.client.Database("data").Collection("deviceData"), &m.config.lastUpdatedId, ) @@ -93,7 +101,7 @@ func (m *Migration) RunAndExit() { } lastFetchedID := m.migrationUtil.GetLastID() - selector, opt := utils.JellyfishUpdatesQuery( + selector, opt := utils.JellyfishDataQuery( &m.config.userID, &lastFetchedID, m.config.queryBatchSize, @@ -101,7 +109,7 @@ func (m *Migration) RunAndExit() { ) if m.config.rollback { - selector, opt = utils.JellyfishRollbackQuery( + selector, opt = utils.JellyfishDataRollbackQuery( m.config.rollbackSectionName, &m.config.userID, &lastFetchedID, @@ -109,7 +117,7 @@ func (m *Migration) RunAndExit() { m.config.queryLimit, ) } - if err := m.migrationUtil.Execute(selector, opt, utils.ProcessJellyfishQueryFn, utils.WriteJellyfishUpdatesFn); err != nil { + if err := m.migrationUtil.Execute(selector, opt, utils.JellyfishDataQueryFn, utils.JellyfishDataUpdatesFn); err != nil { log.Printf("execute failed: %s", err) return err } diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go new file mode 100644 index 0000000000..3e275a55ca --- /dev/null +++ b/migrations/20231128_jellyfish_migration/utils/data_migration.go @@ -0,0 +1,413 @@ +package utils + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "log" + "os" + "path/filepath" + "strings" + "time" + + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + +type UpdateData struct { + Filter interface{} `json:"-"` + ItemID string `json:"_id"` + UserID string `json:"_userId"` + ItemType string `json:"-"` + Apply []bson.M `json:"apply"` + ApplyLast bson.M `json:"applyLast"` + Revert []bson.M `json:"revert"` +} + +type ErrorData struct { + Error error `json:"error"` + ItemID string `json:"_id"` + ItemType string `json:"-"` + Msg string `json:"message,omitempty"` +} + +type MigrationStats struct { + Errored int + Fetched int + Applied int + ToApply int + Elapsed time.Duration +} + +type Settings struct { + DryRun bool + Rollback bool + RollbackSectionName string + StopOnErr bool + Cap *int + WriteBatchSize *int64 +} + +type DataMigrationConfig struct { + writeToDisk bool + //apply no changes + dryRun bool + //rollback the changes that have been applied + rollback bool + //name of section with mongo document that stores the original values + rollbackSectionName string + //halt on error + stopOnErr bool + // cap for number of items to migrate + cap *int +} + +func NewDataMigrationConfig(dryRun *bool, stopOnErr *bool, rollback *bool, rollbackSectionName *string, cap *int, writeToDisk *bool) *DataMigrationConfig { + cfg := &DataMigrationConfig{ + writeToDisk: false, + rollback: true, + rollbackSectionName: "_rollbackMigration", + dryRun: true, + stopOnErr: true, + } + if dryRun != nil { + cfg.SetDryRun(*dryRun) + } + if stopOnErr != nil { + cfg.SetStopOnErr(*stopOnErr) + } + if rollback != nil { + cfg.SetRollback(*rollback) + } + if rollbackSectionName != nil { + cfg.SetRollbackSectionName(*rollbackSectionName) + } + if cap != nil && *cap > 0 { + cfg.cap = cap + log.Printf("capped at %d items", *cfg.cap) + } + return cfg +} + +func (c *DataMigrationConfig) SetDryRun(dryRun bool) *DataMigrationConfig { + c.dryRun = dryRun + return c +} +func (c *DataMigrationConfig) SetStopOnErr(stopOnErr bool) *DataMigrationConfig { + c.stopOnErr = stopOnErr + return c +} +func (c *DataMigrationConfig) SetRollback(rollback bool) *DataMigrationConfig { + c.rollback = rollback + return c +} +func (c *DataMigrationConfig) SetRollbackSectionName(rollbackSectionName string) *DataMigrationConfig { + c.rollbackSectionName = rollbackSectionName + return c +} +func (c *DataMigrationConfig) SetWriteToDisk(writeToDisk bool) *DataMigrationConfig { + c.writeToDisk = writeToDisk + return c +} + +type DataMigration struct { + ctx context.Context + dataC *mongo.Collection + config *DataMigrationConfig + updates []mongo.WriteModel + groupedDiffs map[string][]UpdateData + groupedErrors groupedErrors + rawData []bson.M + errorsCount int + updatedCount int + lastUpdatedId string + startedAt time.Time + mongoInstanceChecker MongoInstanceCheck +} + +type DataMigrationQueryFn func(m *DataMigration, selector bson.M, opts ...*options.FindOptions) bool +type DataMigrationUpdateFn func(m *DataMigration) (int, error) + +type groupedErrors map[string][]ErrorData + +func NewMigration(ctx context.Context, config *DataMigrationConfig, checker MongoInstanceCheck, dataC *mongo.Collection, lastID *string) (*DataMigration, error) { + var err error + if config == nil { + err = errors.Join(err, errors.New("missing required configuration")) + } + if checker == nil { + err = errors.Join(err, errors.New("missing required mongo checker")) + } + + if err != nil { + return nil, err + } + + m := &DataMigration{ + ctx: ctx, + dataC: dataC, + mongoInstanceChecker: checker, + config: config, + updates: []mongo.WriteModel{}, + rawData: []bson.M{}, + groupedErrors: groupedErrors{}, + groupedDiffs: map[string][]UpdateData{}, + errorsCount: 0, + updatedCount: 0, + startedAt: time.Now(), + } + if lastID != nil { + m.lastUpdatedId = *lastID + } + return m, nil +} + +func (m *DataMigration) Initialize() error { + if err := m.mongoInstanceChecker.CheckFreeSpace(m.ctx, m.dataC); err != nil { + return err + } + if err := m.mongoInstanceChecker.SetWriteBatchSize(m.ctx); err != nil { + return err + } + return nil +} + +func (m *DataMigration) GetCtx() context.Context { + return m.ctx +} + +func (m *DataMigration) GetSettings() Settings { + return Settings{ + DryRun: m.config.dryRun, + Rollback: m.config.rollback, + RollbackSectionName: m.config.rollbackSectionName, + Cap: m.config.cap, + StopOnErr: m.config.stopOnErr, + WriteBatchSize: m.mongoInstanceChecker.GetWriteBatchSize(), + } +} + +func (m *DataMigration) GetDataCollection() *mongo.Collection { + return m.dataC +} + +func (m *DataMigration) Execute( + selector bson.M, + selectorOpt *options.FindOptions, + queryFn DataMigrationQueryFn, + updateFn DataMigrationUpdateFn) error { + for queryFn(m, selector, selectorOpt) { + count, err := updateFn(m) + if err != nil { + m.writeErrors(nil) + return err + } + m.updatedCount += count + if m.capReached() { + break + } + } + m.GetStats().report() + m.writeErrors(nil) + m.writeAudit(nil) + return nil +} + +func (d UpdateData) GetMongoUpdates(rollback bool, rollbackSectionName string) []mongo.WriteModel { + updates := []mongo.WriteModel{} + for _, u := range d.Apply { + updateOp := mongo.NewUpdateOneModel() + updateOp.Filter = d.Filter + updateOp.SetUpdate(u) + updates = append(updates, updateOp) + } + updateOp := mongo.NewUpdateOneModel() + updateOp.Filter = d.Filter + if !rollback && len(d.Revert) > 0 { + updateOp.SetUpdate(bson.M{"$set": bson.M{rollbackSectionName: d.Revert}}) + } else if rollback { + updateOp.SetUpdate(bson.M{"$unset": bson.M{rollbackSectionName: ""}}) + } + updates = append(updates, updateOp) + return updates +} + +func (m *DataMigration) SetUpdates(data UpdateData) { + m.groupedDiffs[data.ItemType] = append(m.groupedDiffs[data.ItemType], data) + m.updates = append(m.updates, data.GetMongoUpdates(m.config.rollback, m.config.rollbackSectionName)...) +} + +func (m *DataMigration) ResetUpdates() { + m.updates = []mongo.WriteModel{} +} + +func (m *DataMigration) GetUpdates() []mongo.WriteModel { + return m.updates +} + +func (m *DataMigration) SetLastProcessed(lastID string) { + m.lastUpdatedId = lastID + m.writeLastProcessed(m.lastUpdatedId) +} + +func (m *DataMigration) SetFetched(raw []bson.M) { + m.rawData = append(m.rawData, raw...) +} + +func (m *DataMigration) GetStats() MigrationStats { + return MigrationStats{ + Errored: m.errorsCount, + Fetched: len(m.rawData), + ToApply: len(m.updates), + Applied: m.updatedCount, + Elapsed: time.Since(m.startedAt).Truncate(time.Millisecond), + } +} + +func (m *DataMigration) GetLastID() string { + return m.lastUpdatedId +} + +func (m *DataMigration) OnError(data ErrorData) { + m.errorsCount++ + m.groupedErrors[data.ItemType] = append(m.groupedErrors[data.ItemType], data) + var errFormat = "[_id=%s] %s %s\n" + + if m.config.stopOnErr { + log.Printf(errFormat, data.ItemID, data.Msg, data.Error.Error()) + os.Exit(1) + } +} + +func (m *DataMigration) UpdateChecks() error { + if err := m.mongoInstanceChecker.BlockUntilDBReady(m.GetCtx()); err != nil { + return err + } + if err := m.mongoInstanceChecker.CheckFreeSpace(m.GetCtx(), m.GetDataCollection()); err != nil { + return err + } + return nil +} + +func (m *DataMigration) capReached() bool { + if m.config.cap != nil { + stats := m.GetStats() + + percent := (float64(stats.Fetched) * float64(100)) / float64(*m.config.cap) + log.Printf("processed %.0f %% of %d records and applied %d changes", percent, *m.config.cap, stats.Applied) + + if *m.config.cap <= stats.Applied || *m.config.cap <= stats.Fetched { + log.Printf("cap [%d] updates applied [%d] fetched [%d]", *m.config.cap, stats.Applied, stats.Fetched) + return true + } + } + return false +} + +func (c MigrationStats) report() { + if c.Applied == 0 && c.Fetched > 0 { + log.Printf("elapsed [%s] for [%d] items fetched with [%d] errors\n", c.Elapsed, c.Fetched, c.Errored) + return + } + log.Printf("elapsed [%s] for [%d] fetched [%d] updates applied with [%d] errors\n", c.Elapsed, c.Fetched, c.Applied, c.Errored) +} + +func (m *DataMigration) writeErrors(groupLimit *int) { + if m.config.writeToDisk { + for group, errors := range m.groupedErrors { + if groupLimit != nil { + if len(errors) < *groupLimit { + continue + } + } + f, err := createFile("error", group, "%s.log") + if err != nil { + log.Println(err) + os.Exit(1) + } + defer f.Close() + for _, data := range errors { + errJSON, err := json.Marshal(data) + if err != nil { + log.Println(err) + os.Exit(1) + } + f.WriteString(string(errJSON) + "\n") + } + m.groupedErrors[group] = []ErrorData{} + } + } +} + +func (m *DataMigration) writeAudit(groupLimit *int) { + + if !m.config.dryRun { + m.groupedDiffs = map[string][]UpdateData{} + return + } + if m.config.writeToDisk { + + for group, diffs := range m.groupedDiffs { + if groupLimit != nil { + if len(diffs) < *groupLimit { + continue + } + } + f, err := createFile("audit", group, "%s.json") + if err != nil { + log.Println(err) + os.Exit(1) + } + defer f.Close() + for _, data := range diffs { + diffJSON, err := json.Marshal(data) + if err != nil { + log.Println(err) + os.Exit(1) + } + f.WriteString(string(diffJSON) + "\n") + } + m.groupedDiffs[group] = []UpdateData{} + } + } +} + +func (m *DataMigration) writeLastProcessed(itemID string) { + if m.config.writeToDisk { + if strings.TrimSpace(itemID) != "" { + f, err := os.Create("./lastProcessedId") + if err != nil { + log.Println(err) + os.Exit(1) + } + defer f.Close() + f.WriteString(itemID) + } + } +} + +func createFile(fileType string, dataGroup string, logName string) (*os.File, error) { + var err error + if fileType == "" { + errors.Join(err, errors.New("missing file type")) + } + if dataGroup == "" { + errors.Join(err, errors.New("missing data group")) + } + if logName == "" { + errors.Join(err, errors.New("missing log group")) + } + if err != nil { + return nil, err + } + logName = fmt.Sprintf(logName, dataGroup) + logPath := filepath.Join(".", fileType) + + err = os.MkdirAll(logPath, os.ModePerm) + if err != nil { + return nil, err + } + return os.OpenFile(logPath+"/"+logName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) +} diff --git a/migrations/20231128_jellyfish_migration/utils/migration_test.go b/migrations/20231128_jellyfish_migration/utils/data_migration_test.go similarity index 55% rename from migrations/20231128_jellyfish_migration/utils/migration_test.go rename to migrations/20231128_jellyfish_migration/utils/data_migration_test.go index e6430e2896..13b692fabb 100644 --- a/migrations/20231128_jellyfish_migration/utils/migration_test.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration_test.go @@ -14,109 +14,31 @@ import ( logTest "github.com/tidepool-org/platform/log/test" "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils/test" + "github.com/tidepool-org/platform/pointer" storeStructuredMongoTest "github.com/tidepool-org/platform/store/structured/mongo/test" ) -type fakeMigrator struct { - rollback bool - rollbackSectionName string - ctx context.Context - dataC *mongo.Collection - updates []mongo.WriteModel - rawData []bson.M - errorsCount int - updatedCount int - lastUpdatedId string +type mongoInstance struct { + writeBatchSize *int64 } -func newMigrationUtil(dataC *mongo.Collection, rollback bool) utils.Migration { - return &fakeMigrator{ - ctx: context.Background(), - dataC: dataC, - rollback: rollback, - rollbackSectionName: "_testRollback", - updates: []mongo.WriteModel{}, - rawData: []bson.M{}, - errorsCount: 0, - updatedCount: 0, +func newMongoInstanceChecker() utils.MongoInstanceCheck { + return &mongoInstance{ + writeBatchSize: pointer.FromInt64(100), } } -func (m *fakeMigrator) Initialize() error { +func (m *mongoInstance) SetWriteBatchSize(ctx context.Context) error { return nil } -func (m *fakeMigrator) Execute(selector bson.M, selectorOpt *options.FindOptions, queryFn utils.MigrationQueryFn, updateFn utils.MigrationUpdateFn) error { - settings := m.GetSettings() - for queryFn(m, selector, selectorOpt) { - updated, err := updateFn(m) - if err != nil { - return err - } - m.updatedCount += updated - if settings.Cap != nil { - if m.GetStats().Fetched >= *settings.Cap { - break - } - } - } +func (m *mongoInstance) CheckFreeSpace(ctx context.Context, dataC *mongo.Collection) error { return nil } -func (m *fakeMigrator) OnError(data utils.ErrorData) { - m.errorsCount++ -} -func (m *fakeMigrator) SetUpdates(data utils.UpdateData) { - m.updates = append(m.updates, data.GetMongoUpdates(m.rollback, m.rollbackSectionName)...) -} -func (m *fakeMigrator) GetUpdates() []mongo.WriteModel { - return m.updates -} - -func (m *fakeMigrator) GetSettings() utils.Settings { - writeBatchSize := int64(20) - return utils.Settings{ - DryRun: false, - Rollback: m.rollback, - RollbackSectionName: m.rollbackSectionName, - StopOnErr: false, - Cap: nil, - WriteBatchSize: &writeBatchSize, - } -} - -func (m *fakeMigrator) ResetUpdates() { - m.updates = []mongo.WriteModel{} -} - -func (m *fakeMigrator) GetCtx() context.Context { - return context.Background() -} - -func (m *fakeMigrator) GetLastID() string { - return m.lastUpdatedId -} - -func (m *fakeMigrator) SetLastProcessed(lastID string) { - m.lastUpdatedId = lastID -} - -func (m *fakeMigrator) GetDataCollection() *mongo.Collection { - return m.dataC -} - -func (m *fakeMigrator) UpdateChecks() error { +func (m *mongoInstance) BlockUntilDBReady(ctx context.Context) error { return nil } - -func (m *fakeMigrator) SetFetched(raw []bson.M) { - m.rawData = append(m.rawData, raw...) -} - -func (m *fakeMigrator) GetStats() utils.MigrationStats { - return utils.MigrationStats{ - Errored: m.errorsCount, - Fetched: len(m.rawData), - Applied: m.updatedCount, - } +func (m *mongoInstance) GetWriteBatchSize() *int64 { + return m.writeBatchSize } func setCollectionData(ctx context.Context, dataC *mongo.Collection, dataSetData []map[string]interface{}) error { @@ -133,15 +55,32 @@ var _ = Describe("back-37", func() { var _ = Describe("migrationUtil", func() { var testData []map[string]interface{} - var migration utils.Migration const datumCount = 1000 var store *dataStoreMongo.Store var ctx context.Context + var rollbackConfig *utils.DataMigrationConfig + var migtaionConfig *utils.DataMigrationConfig BeforeEach(func() { logger := logTest.NewLogger() ctx = platformLog.NewContextWithLogger(context.Background(), logger) testData = test.BulkJellyfishData("test-device-88x89", "test-group-id", "test-user-id-123", datumCount) + rollbackConfig = utils.NewDataMigrationConfig( + pointer.FromBool(false), + pointer.FromBool(false), + pointer.FromBool(true), + pointer.FromString("_testRollback"), + nil, + pointer.FromBool(false), + ) + migtaionConfig = utils.NewDataMigrationConfig( + pointer.FromBool(false), + pointer.FromBool(false), + pointer.FromBool(false), + pointer.FromString("_testRollback"), + nil, + pointer.FromBool(false), + ) var err error store, err = dataStoreMongo.NewStore(storeStructuredMongoTest.NewConfig()) Expect(err).ToNot(HaveOccurred()) @@ -156,14 +95,16 @@ var _ = Describe("back-37", func() { collection := store.GetCollection("testMigration") Expect(setCollectionData(ctx, collection, testData)).To(Succeed()) - migration = newMigrationUtil(collection, false) + migration, err := utils.NewMigration(ctx, migtaionConfig, newMongoInstanceChecker(), collection, nil) + Expect(err).To(BeNil()) + Expect(testData).ToNot(BeNil()) Expect(len(testData)).To(Equal(datumCount)) allDocs, err := collection.CountDocuments(ctx, bson.D{}) Expect(err).To(BeNil()) Expect(allDocs).To(Equal(int64(datumCount))) - selector, opt := utils.JellyfishUpdatesQuery(nil, nil, 50, 100) - Expect(migration.Execute(selector, opt, utils.ProcessJellyfishQueryFn, utils.WriteJellyfishUpdatesFn)).To(Succeed()) + selector, opt := utils.JellyfishDataQuery(nil, nil, 50, 100) + Expect(migration.Execute(selector, opt, utils.JellyfishDataQueryFn, utils.JellyfishDataUpdatesFn)).To(Succeed()) stats := migration.GetStats() Expect(stats.Errored).To(Equal(0)) Expect(stats.Fetched).To(Equal(datumCount)) @@ -192,7 +133,9 @@ var _ = Describe("back-37", func() { findOptions := options.Find() findOptions.SetSort(bson.D{{Key: "_id", Value: -1}}) - migration = newMigrationUtil(collection, false) + migration, err := utils.NewMigration(ctx, migtaionConfig, newMongoInstanceChecker(), collection, nil) + Expect(err).To(BeNil()) + Expect(testData).ToNot(BeNil()) Expect(len(testData)).To(Equal(datumCount)) @@ -203,8 +146,8 @@ var _ = Describe("back-37", func() { cur.All(ctx, &original) Expect(len(original)).To(Equal(datumCount)) - selector, opt := utils.JellyfishUpdatesQuery(nil, nil, 50, 100) - Expect(migration.Execute(selector, opt, utils.ProcessJellyfishQueryFn, utils.WriteJellyfishUpdatesFn)).To(Succeed()) + selector, opt := utils.JellyfishDataQuery(nil, nil, 50, 100) + Expect(migration.Execute(selector, opt, utils.JellyfishDataQueryFn, utils.JellyfishDataUpdatesFn)).To(Succeed()) cur, err = collection.Find(ctx, bson.D{}, findOptions) Expect(err).To(BeNil()) @@ -212,10 +155,11 @@ var _ = Describe("back-37", func() { cur.All(ctx, &migrated) Expect(len(migrated)).To(Equal(datumCount)) - rollback := newMigrationUtil(collection, true) + rollback, err := utils.NewMigration(ctx, rollbackConfig, newMongoInstanceChecker(), collection, nil) + Expect(err).To(BeNil()) - rollbackSelector, rollbackOpt := utils.JellyfishRollbackQuery(rollback.GetSettings().RollbackSectionName, nil, nil, 50, 100) - Expect(rollback.Execute(rollbackSelector, rollbackOpt, utils.ProcessJellyfishQueryFn, utils.WriteJellyfishUpdatesFn)).To(Succeed()) + rollbackSelector, rollbackOpt := utils.JellyfishDataRollbackQuery(rollback.GetSettings().RollbackSectionName, nil, nil, 50, 100) + Expect(rollback.Execute(rollbackSelector, rollbackOpt, utils.JellyfishDataQueryFn, utils.JellyfishDataUpdatesFn)).To(Succeed()) cur, err = collection.Find(ctx, bson.D{}, findOptions) Expect(err).To(BeNil()) diff --git a/migrations/20231128_jellyfish_migration/utils/jellyfish.go b/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go similarity index 89% rename from migrations/20231128_jellyfish_migration/utils/jellyfish.go rename to migrations/20231128_jellyfish_migration/utils/jellyfish_data.go index 70d9519605..e3abdd50ed 100644 --- a/migrations/20231128_jellyfish_migration/utils/jellyfish.go +++ b/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go @@ -36,7 +36,7 @@ func opt(batchSize int32, queryLimit int64) *options.FindOptions { } } -func JellyfishUpdatesQuery(userID *string, lastFetchedID *string, batchSize int64, queryLimit int64) (bson.M, *options.FindOptions) { +func JellyfishDataQuery(userID *string, lastFetchedID *string, batchSize int64, queryLimit int64) (bson.M, *options.FindOptions) { selector := bson.M{ "_deduplicator": bson.M{"$exists": false}, } @@ -44,7 +44,7 @@ func JellyfishUpdatesQuery(userID *string, lastFetchedID *string, batchSize int6 return selector, opt(int32(batchSize), queryLimit) } -func JellyfishRollbackQuery(rollbackSectionName string, userID *string, lastFetchedID *string, batchSize int64, queryLimit int64) (bson.M, *options.FindOptions) { +func JellyfishDataRollbackQuery(rollbackSectionName string, userID *string, lastFetchedID *string, batchSize int64, queryLimit int64) (bson.M, *options.FindOptions) { selector := bson.M{ rollbackSectionName: bson.M{"$exists": true}, } @@ -52,7 +52,7 @@ func JellyfishRollbackQuery(rollbackSectionName string, userID *string, lastFetc return selector, opt(int32(batchSize), queryLimit) } -var ProcessJellyfishQueryFn = func(m Migration, selector bson.M, opts ...*options.FindOptions) bool { +var JellyfishDataQueryFn = func(m *DataMigration, selector bson.M, opts ...*options.FindOptions) bool { if dataC := m.GetDataCollection(); dataC != nil { dDataCursor, err := dataC.Find(m.GetCtx(), selector, opts...) if err != nil { @@ -115,7 +115,7 @@ var ProcessJellyfishQueryFn = func(m Migration, selector bson.M, opts ...*option return false } -var WriteJellyfishUpdatesFn = func(m Migration) (int, error) { +var JellyfishDataUpdatesFn = func(m *DataMigration) (int, error) { settings := m.GetSettings() updates := m.GetUpdates() dataC := m.GetDataCollection() diff --git a/migrations/20231128_jellyfish_migration/utils/migration.go b/migrations/20231128_jellyfish_migration/utils/migration.go deleted file mode 100644 index caab53f0ab..0000000000 --- a/migrations/20231128_jellyfish_migration/utils/migration.go +++ /dev/null @@ -1,156 +0,0 @@ -package utils - -import ( - "context" - "log" - "time" - - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" -) - -type UpdateData struct { - Filter interface{} `json:"-"` - ItemID string `json:"_id"` - UserID string `json:"_userId"` - ItemType string `json:"-"` - Apply []bson.M `json:"apply"` - ApplyLast bson.M `json:"applyLast"` - Revert []bson.M `json:"revert"` -} - -type ErrorData struct { - Error error `json:"error"` - ItemID string `json:"_id"` - ItemType string `json:"-"` - Msg string `json:"message,omitempty"` -} - -type MigrationStats struct { - Errored int - Fetched int - Applied int - ToApply int - Elapsed time.Duration -} - -type MigrationQueryFn = func(mUtil Migration, selector bson.M, opts ...*options.FindOptions) bool - -type MigrationUpdateFn = func(mUtil Migration) (int, error) - -type Migration interface { - Initialize() error - Execute(selector bson.M, opt *options.FindOptions, queryFn MigrationQueryFn, updateFn MigrationUpdateFn) error - GetSettings() Settings - GetLastID() string - UpdateChecks() error - GetCtx() context.Context - GetDataCollection() *mongo.Collection - OnError(data ErrorData) - SetUpdates(data UpdateData) - GetUpdates() []mongo.WriteModel - ResetUpdates() - SetLastProcessed(lastID string) - SetFetched(raw []bson.M) - GetStats() MigrationStats -} - -type Settings struct { - DryRun bool - Rollback bool - RollbackSectionName string - StopOnErr bool - Cap *int - WriteBatchSize *int64 -} - -type MigrationConfig struct { - //apply no changes - dryRun bool - //rollback the changes that have been applied - rollback bool - //name of section with mongo document that stores the original values - rollbackSectionName string - //halt on error - stopOnErr bool - minOplogWindow int - // these values are used to determine writes batches, first dividing the oplog's size with the desired duration and - // expected entry size, then adding a divisor to account for NOP overshoot in the oplog - expectedOplogEntrySize int - // how much of the oplog is NOP, this adjusts the batch to account for an oplog that is very change sensitive - // must be > 0 - // prod 0.6 - // idle 100 - nopPercent int - // minimum free disk space percent - minFreePercent int - // cap for number of items to migrate - cap *int -} - -func NewMigrationConfig(dryRun *bool, stopOnErr *bool, rollback *bool, rollbackSectionName *string, nopPercent *int, cap *int) *MigrationConfig { - cfg := &MigrationConfig{ - minOplogWindow: 28800, // 8hrs - minFreePercent: 10, - expectedOplogEntrySize: 420, - rollback: true, - rollbackSectionName: "_rollbackMigration", - dryRun: true, - stopOnErr: true, - nopPercent: 25, - } - if dryRun != nil { - cfg.SetDryRun(*dryRun) - } - if stopOnErr != nil { - cfg.SetStopOnErr(*stopOnErr) - } - if rollback != nil { - cfg.SetRollback(*rollback) - } - if rollbackSectionName != nil { - cfg.SetRollbackSectionName(*rollbackSectionName) - } - if nopPercent != nil { - cfg.SetNopPercent(*nopPercent) - } - if cap != nil && *cap > 0 { - cfg.cap = cap - log.Printf("capped at %d items", *cfg.cap) - } - return cfg -} - -func (c *MigrationConfig) SetNopPercent(nopPercent int) *MigrationConfig { - c.nopPercent = nopPercent - return c -} -func (c *MigrationConfig) SetMinOplogWindow(minOplogWindow int) *MigrationConfig { - c.minOplogWindow = minOplogWindow - return c -} -func (c *MigrationConfig) SetExpectedOplogEntrySize(expectedOplogEntrySize int) *MigrationConfig { - c.expectedOplogEntrySize = expectedOplogEntrySize - return c -} -func (c *MigrationConfig) SetMinFreePercent(minFreePercent int) *MigrationConfig { - c.minFreePercent = minFreePercent - return c -} -func (c *MigrationConfig) SetDryRun(dryRun bool) *MigrationConfig { - c.dryRun = dryRun - return c -} -func (c *MigrationConfig) SetStopOnErr(stopOnErr bool) *MigrationConfig { - c.stopOnErr = stopOnErr - return c -} -func (c *MigrationConfig) SetRollback(rollback bool) *MigrationConfig { - c.rollback = rollback - return c -} -func (c *MigrationConfig) SetRollbackSectionName(rollbackSectionName string) *MigrationConfig { - c.rollbackSectionName = rollbackSectionName - return c -} diff --git a/migrations/20231128_jellyfish_migration/utils/migrationImpl.go b/migrations/20231128_jellyfish_migration/utils/migrationImpl.go deleted file mode 100644 index 08f332f428..0000000000 --- a/migrations/20231128_jellyfish_migration/utils/migrationImpl.go +++ /dev/null @@ -1,458 +0,0 @@ -package utils - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "log" - "math" - "os" - "path/filepath" - "strings" - "time" - - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" -) - -type migrationImpl struct { - ctx context.Context - dataC *mongo.Collection - writeBatchSize *int64 - client *mongo.Client - config *MigrationConfig - updates []mongo.WriteModel - groupedDiffs map[string][]UpdateData - groupedErrors groupedErrors - rawData []bson.M - errorsCount int - updatedCount int - lastUpdatedId string - startedAt time.Time -} - -type groupedErrors map[string][]ErrorData - -func NewMigration(ctx context.Context, config *MigrationConfig, client *mongo.Client, dataC *mongo.Collection, lastID *string) (Migration, error) { - var err error - if config == nil { - err = errors.Join(err, errors.New("missing required configuration")) - } - if client == nil { - err = errors.Join(err, errors.New("missing required mongo client")) - } - - if err != nil { - return nil, err - } - - m := &migrationImpl{ - ctx: ctx, - dataC: dataC, - client: client, - config: config, - updates: []mongo.WriteModel{}, - rawData: []bson.M{}, - groupedErrors: groupedErrors{}, - groupedDiffs: map[string][]UpdateData{}, - errorsCount: 0, - updatedCount: 0, - startedAt: time.Now(), - } - if lastID != nil { - m.lastUpdatedId = *lastID - } - return m, nil -} - -func (m *migrationImpl) Initialize() error { - if err := m.checkFreeSpace(m.ctx, m.dataC); err != nil { - return err - } - if err := m.setWriteBatchSize(m.ctx); err != nil { - return err - } - return nil -} - -func (m *migrationImpl) GetCtx() context.Context { - return m.ctx -} - -func (m *migrationImpl) GetSettings() Settings { - return Settings{ - DryRun: m.config.dryRun, - Rollback: m.config.rollback, - RollbackSectionName: m.config.rollbackSectionName, - Cap: m.config.cap, - StopOnErr: m.config.stopOnErr, - WriteBatchSize: m.writeBatchSize, - } -} - -func (m *migrationImpl) GetDataCollection() *mongo.Collection { - return m.dataC -} - -func (m *migrationImpl) Execute( - selector bson.M, - selectorOpt *options.FindOptions, - queryFn MigrationQueryFn, - updateFn MigrationUpdateFn) error { - for queryFn(m, selector, selectorOpt) { - var err error - m.updatedCount, err = updateFn(m) - if err != nil { - m.writeErrors(nil) - return err - } - if m.capReached() { - break - } - } - m.GetStats().report() - m.writeErrors(nil) - m.writeAudit(nil) - return nil -} - -func (d UpdateData) GetMongoUpdates(rollback bool, rollbackSectionName string) []mongo.WriteModel { - updates := []mongo.WriteModel{} - for _, u := range d.Apply { - updateOp := mongo.NewUpdateOneModel() - updateOp.Filter = d.Filter - updateOp.SetUpdate(u) - updates = append(updates, updateOp) - } - updateOp := mongo.NewUpdateOneModel() - updateOp.Filter = d.Filter - if !rollback && len(d.Revert) > 0 { - updateOp.SetUpdate(bson.M{"$set": bson.M{rollbackSectionName: d.Revert}}) - } else if rollback { - updateOp.SetUpdate(bson.M{"$unset": bson.M{rollbackSectionName: ""}}) - } - updates = append(updates, updateOp) - return updates -} - -func (m *migrationImpl) SetUpdates(data UpdateData) { - m.groupedDiffs[data.ItemType] = append(m.groupedDiffs[data.ItemType], data) - m.updates = append(m.updates, data.GetMongoUpdates(m.config.rollback, m.config.rollbackSectionName)...) -} - -func (m *migrationImpl) ResetUpdates() { - m.updates = []mongo.WriteModel{} -} - -func (m *migrationImpl) GetUpdates() []mongo.WriteModel { - return m.updates -} - -func (m *migrationImpl) SetLastProcessed(lastID string) { - m.lastUpdatedId = lastID - writeLastProcessed(m.lastUpdatedId) -} - -func (m *migrationImpl) SetFetched(raw []bson.M) { - m.rawData = append(m.rawData, raw...) -} - -func (m *migrationImpl) GetStats() MigrationStats { - return MigrationStats{ - Errored: m.errorsCount, - Fetched: len(m.rawData), - ToApply: len(m.updates), - Applied: m.updatedCount, - Elapsed: time.Since(m.startedAt).Truncate(time.Millisecond), - } -} - -func (m *migrationImpl) GetLastID() string { - return m.lastUpdatedId -} - -func (m *migrationImpl) OnError(data ErrorData) { - m.errorsCount++ - m.groupedErrors[data.ItemType] = append(m.groupedErrors[data.ItemType], data) - var errFormat = "[_id=%s] %s %s\n" - - if m.config.stopOnErr { - log.Printf(errFormat, data.ItemID, data.Msg, data.Error.Error()) - os.Exit(1) - } -} - -func (m *migrationImpl) UpdateChecks() error { - if err := m.blockUntilDBReady(m.GetCtx()); err != nil { - return err - } - if err := m.checkFreeSpace(m.GetCtx(), m.GetDataCollection()); err != nil { - return err - } - return nil -} - -func (m *migrationImpl) capReached() bool { - if m.config.cap != nil { - stats := m.GetStats() - - percent := (float64(stats.Fetched) * float64(100)) / float64(*m.config.cap) - log.Printf("processed %.0f %% of %d records and applied %d changes", percent, *m.config.cap, stats.Applied) - - if *m.config.cap <= stats.Applied || *m.config.cap <= stats.Fetched { - log.Printf("cap [%d] updates applied [%d] fetched [%d]", *m.config.cap, stats.Applied, stats.Fetched) - return true - } - } - return false -} - -func (c MigrationStats) report() { - if c.Applied == 0 && c.Fetched > 0 { - log.Printf("elapsed [%s] for [%d] items fetched with [%d] errors\n", c.Elapsed, c.Fetched, c.Errored) - return - } - log.Printf("elapsed [%s] for [%d] items migrated with [%d] errors\n", c.Elapsed, c.Applied, c.Errored) -} - -func (m *migrationImpl) getOplogCollection() *mongo.Collection { - return m.client.Database("local").Collection("oplog.rs") -} - -func (m *migrationImpl) getAdminDB() *mongo.Database { - return m.client.Database("admin") -} - -func (m *migrationImpl) getOplogDuration(ctx context.Context) (time.Duration, error) { - type MongoMetaData struct { - Wall time.Time `json:"wall"` - } - if oplogC := m.getOplogCollection(); oplogC != nil { - var oldest MongoMetaData - if err := oplogC.FindOne( - ctx, - bson.M{"wall": bson.M{"$exists": true}}, - options.FindOne().SetSort(bson.M{"$natural": 1})).Decode(&oldest); err != nil { - return 0, err - } - - var newest MongoMetaData - if err := oplogC.FindOne( - ctx, - bson.M{"wall": bson.M{"$exists": true}}, - options.FindOne().SetSort(bson.M{"$natural": -1})).Decode(&newest); err != nil { - return 0, err - } - oplogDuration := newest.Wall.Sub(oldest.Wall) - return oplogDuration, nil - } - log.Println("Not clustered, not retrieving oplog duration.") - oplogDuration := time.Duration(m.config.minOplogWindow+1) * time.Second - return oplogDuration, nil -} - -func (m *migrationImpl) setWriteBatchSize(ctx context.Context) error { - var calculateBatchSize = func(oplogSize int, oplogEntryBytes int, oplogMinWindow int, nopPercent int) int64 { - return int64(math.Floor(float64(oplogSize) / float64(oplogEntryBytes) / float64(oplogMinWindow) / (float64(nopPercent) / 7))) - } - - if oplogC := m.getOplogCollection(); oplogC != nil { - type MongoMetaData struct { - MaxSize int `json:"maxSize"` - } - var metaData MongoMetaData - if err := oplogC.Database().RunCommand(ctx, bson.M{"collStats": "oplog.rs"}).Decode(&metaData); err != nil { - return err - } - writeBatchSize := calculateBatchSize(metaData.MaxSize, m.config.expectedOplogEntrySize, m.config.minOplogWindow, m.config.nopPercent) - m.writeBatchSize = &writeBatchSize - log.Printf("calculated writeBatchSize: %d", writeBatchSize) - return nil - } - var writeBatchSize = int64(30000) - log.Printf("MongoDB is not clustered, removing write batch limit, setting to %d documents.", writeBatchSize) - m.writeBatchSize = &writeBatchSize - return nil -} - -func (m *migrationImpl) checkFreeSpace(ctx context.Context, dataC *mongo.Collection) error { - // pass in config and mongo collection being migrated - if dataC == nil { - return errors.New("missing required mongo data collection") - } - - type MongoMetaData struct { - FsTotalSize int `json:"fsTotalSize"` - FsUsedSize int `json:"fsUsedSize"` - } - var metaData MongoMetaData - if dataC != nil { - if err := dataC.Database().RunCommand(ctx, bson.M{"dbStats": 1}).Decode(&metaData); err != nil { - return err - } - bytesFree := metaData.FsTotalSize - metaData.FsUsedSize - percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) - if m.config.minFreePercent > percentFree { - return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) - } - return nil - } - return errors.New("could not get deviceData database") -} - -func (m *migrationImpl) getWaitTime(ctx context.Context) (float64, error) { - type Member struct { - Name string `json:"name"` - Health int `json:"health"` - Uptime int `json:"uptime"` - State int `json:"state"` - } - - type MongoMetaData struct { - Members []Member `json:"members"` - } - - var metaData MongoMetaData - if err := m.getAdminDB().RunCommand(ctx, bson.M{"replSetGetStatus": 1}).Decode(&metaData); err != nil { - return 0, err - } - - for _, member := range metaData.Members { - if member.State < 1 || member.State > 2 || member.Health != 1 || member.Uptime < 120 { - log.Printf("DB member %s down or not ready.", member.Name) - return 240, nil - } - } - - oplogDuration, err := m.getOplogDuration(ctx) - if err != nil { - return 0, err - } - if oplogDuration.Seconds() < float64(m.config.minOplogWindow) { - minOplogWindowTime := time.Duration(m.config.minOplogWindow) * time.Second - log.Printf("DB oplog shorter than requested duration of %s, currently %s.", minOplogWindowTime, oplogDuration) - waitTime := float64(m.config.minOplogWindow) - oplogDuration.Seconds() - waitTime *= 1.15 - if waitTime < 600 { - waitTime = 600 - } - return waitTime, nil - } - return 0, nil -} - -func (m *migrationImpl) blockUntilDBReady(ctx context.Context) error { - waitTime, err := m.getWaitTime(ctx) - if err != nil { - return err - } - var totalWait float64 - for waitTime > 0 { - totalWait += waitTime - if totalWait > 1800 { - log.Printf("Long total wait of %s, possibly high load, or sustained DB outage. If neither, adjust NOP_PERCENT to reduce overshoot.", time.Duration(totalWait)*time.Second) - } - log.Printf("Sleeping for %d", time.Duration(waitTime)*time.Second) - time.Sleep(time.Duration(waitTime) * time.Second) - waitTime, err = m.getWaitTime(ctx) - if err != nil { - log.Printf("failed getting wait time %d", time.Duration(waitTime)*time.Second) - return err - } - } - return nil -} - -func (m *migrationImpl) writeErrors(groupLimit *int) { - for group, errors := range m.groupedErrors { - if groupLimit != nil { - if len(errors) < *groupLimit { - continue - } - } - f, err := createFile("error", group, "%s.log") - if err != nil { - log.Println(err) - os.Exit(1) - } - defer f.Close() - for _, data := range errors { - errJSON, err := json.Marshal(data) - if err != nil { - log.Println(err) - os.Exit(1) - } - f.WriteString(string(errJSON) + "\n") - } - m.groupedErrors[group] = []ErrorData{} - } -} - -func (m *migrationImpl) writeAudit(groupLimit *int) { - - if !m.config.dryRun { - m.groupedDiffs = map[string][]UpdateData{} - return - } - - for group, diffs := range m.groupedDiffs { - if groupLimit != nil { - if len(diffs) < *groupLimit { - continue - } - } - f, err := createFile("audit", group, "%s.json") - if err != nil { - log.Println(err) - os.Exit(1) - } - defer f.Close() - for _, data := range diffs { - diffJSON, err := json.Marshal(data) - if err != nil { - log.Println(err) - os.Exit(1) - } - f.WriteString(string(diffJSON) + "\n") - } - m.groupedDiffs[group] = []UpdateData{} - } -} - -func writeLastProcessed(itemID string) { - if strings.TrimSpace(itemID) != "" { - f, err := os.Create("./lastProcessedId") - if err != nil { - log.Println(err) - os.Exit(1) - } - defer f.Close() - f.WriteString(itemID) - } -} - -func createFile(fileType string, dataGroup string, logName string) (*os.File, error) { - var err error - if fileType == "" { - errors.Join(err, errors.New("missing file type")) - } - if dataGroup == "" { - errors.Join(err, errors.New("missing data group")) - } - if logName == "" { - errors.Join(err, errors.New("missing log group")) - } - if err != nil { - return nil, err - } - logName = fmt.Sprintf(logName, dataGroup) - logPath := filepath.Join(".", fileType) - - err = os.MkdirAll(logPath, os.ModePerm) - if err != nil { - return nil, err - } - return os.OpenFile(logPath+"/"+logName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) -} diff --git a/migrations/20231128_jellyfish_migration/utils/mongo_instance_check.go b/migrations/20231128_jellyfish_migration/utils/mongo_instance_check.go new file mode 100644 index 0000000000..1c7986c69c --- /dev/null +++ b/migrations/20231128_jellyfish_migration/utils/mongo_instance_check.go @@ -0,0 +1,229 @@ +package utils + +import ( + "context" + "errors" + "fmt" + "log" + "math" + "time" + + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + +type MongoInstanceCheckConfig struct { + minOplogWindow int + // these values are used to determine writes batches, first dividing the oplog's size with the desired duration and + // expected entry size, then adding a divisor to account for NOP overshoot in the oplog + expectedOplogEntrySize int + // how much of the oplog is NOP, this adjusts the batch to account for an oplog that is very change sensitive + // must be > 0 + // prod 0.6 + // idle 100 + nopPercent int + // minimum free disk space percent + minFreePercent int +} + +func NewMongoInstanceCheckConfig(nopPercent *int) *MongoInstanceCheckConfig { + cfg := &MongoInstanceCheckConfig{ + minOplogWindow: 28800, // 8hrs + minFreePercent: 10, + expectedOplogEntrySize: 420, + nopPercent: 25, + } + if nopPercent != nil { + cfg.SetNopPercent(*nopPercent) + } + return cfg +} + +func (c *MongoInstanceCheckConfig) SetNopPercent(nopPercent int) *MongoInstanceCheckConfig { + c.nopPercent = nopPercent + return c +} +func (c *MongoInstanceCheckConfig) SetMinOplogWindow(minOplogWindow int) *MongoInstanceCheckConfig { + c.minOplogWindow = minOplogWindow + return c +} +func (c *MongoInstanceCheckConfig) SetExpectedOplogEntrySize(expectedOplogEntrySize int) *MongoInstanceCheckConfig { + c.expectedOplogEntrySize = expectedOplogEntrySize + return c +} +func (c *MongoInstanceCheckConfig) SetMinFreePercent(minFreePercent int) *MongoInstanceCheckConfig { + c.minFreePercent = minFreePercent + return c +} + +type MongoInstanceCheck interface { + BlockUntilDBReady(ctx context.Context) error + CheckFreeSpace(ctx context.Context, dataC *mongo.Collection) error + GetWriteBatchSize() *int64 + SetWriteBatchSize(ctx context.Context) error +} + +type mongoInstance struct { + client *mongo.Client + config *MongoInstanceCheckConfig + writeBatchSize *int64 +} + +func NewMongoInstanceCheck(client *mongo.Client, config *MongoInstanceCheckConfig) MongoInstanceCheck { + return &mongoInstance{ + client: client, + config: config, + } +} + +func (m *mongoInstance) GetWriteBatchSize() *int64 { + return m.writeBatchSize +} + +func (m *mongoInstance) SetWriteBatchSize(ctx context.Context) error { + var calculateBatchSize = func(oplogSize int, oplogEntryBytes int, oplogMinWindow int, nopPercent int) int64 { + return int64(math.Floor(float64(oplogSize) / float64(oplogEntryBytes) / float64(oplogMinWindow) / (float64(nopPercent) / 7))) + } + + if oplogC := m.getOplogCollection(); oplogC != nil { + type MongoMetaData struct { + MaxSize int `json:"maxSize"` + } + var metaData MongoMetaData + if err := oplogC.Database().RunCommand(ctx, bson.M{"collStats": "oplog.rs"}).Decode(&metaData); err != nil { + return err + } + writeBatchSize := calculateBatchSize(metaData.MaxSize, m.config.expectedOplogEntrySize, m.config.minOplogWindow, m.config.nopPercent) + m.writeBatchSize = &writeBatchSize + log.Printf("calculated writeBatchSize: %d", writeBatchSize) + return nil + } + var writeBatchSize = int64(30000) + log.Printf("MongoDB is not clustered, removing write batch limit, setting to %d documents.", writeBatchSize) + m.writeBatchSize = &writeBatchSize + return nil +} + +func (m *mongoInstance) CheckFreeSpace(ctx context.Context, dataC *mongo.Collection) error { + // pass in config and mongo collection being migrated + if dataC == nil { + return errors.New("missing required mongo data collection") + } + + type MongoMetaData struct { + FsTotalSize int `json:"fsTotalSize"` + FsUsedSize int `json:"fsUsedSize"` + } + var metaData MongoMetaData + if dataC != nil { + if err := dataC.Database().RunCommand(ctx, bson.M{"dbStats": 1}).Decode(&metaData); err != nil { + return err + } + bytesFree := metaData.FsTotalSize - metaData.FsUsedSize + percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) + if m.config.minFreePercent > percentFree { + return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) + } + return nil + } + return errors.New("could not get deviceData database") +} + +func (m *mongoInstance) BlockUntilDBReady(ctx context.Context) error { + waitTime, err := m.getWaitTime(ctx) + if err != nil { + return err + } + var totalWait float64 + for waitTime > 0 { + totalWait += waitTime + if totalWait > 1800 { + log.Printf("Long total wait of %s, possibly high load, or sustained DB outage. If neither, adjust NOP_PERCENT to reduce overshoot.", time.Duration(totalWait)*time.Second) + } + log.Printf("Sleeping for %d", time.Duration(waitTime)*time.Second) + time.Sleep(time.Duration(waitTime) * time.Second) + waitTime, err = m.getWaitTime(ctx) + if err != nil { + log.Printf("failed getting wait time %d", time.Duration(waitTime)*time.Second) + return err + } + } + return nil +} +func (m *mongoInstance) getWaitTime(ctx context.Context) (float64, error) { + type Member struct { + Name string `json:"name"` + Health int `json:"health"` + Uptime int `json:"uptime"` + State int `json:"state"` + } + + type MongoMetaData struct { + Members []Member `json:"members"` + } + + var metaData MongoMetaData + if err := m.getAdminDB().RunCommand(ctx, bson.M{"replSetGetStatus": 1}).Decode(&metaData); err != nil { + return 0, err + } + + for _, member := range metaData.Members { + if member.State < 1 || member.State > 2 || member.Health != 1 || member.Uptime < 120 { + log.Printf("DB member %s down or not ready.", member.Name) + return 240, nil + } + } + + oplogDuration, err := m.getOplogDuration(ctx) + if err != nil { + return 0, err + } + if oplogDuration.Seconds() < float64(m.config.minOplogWindow) { + minOplogWindowTime := time.Duration(m.config.minOplogWindow) * time.Second + log.Printf("DB oplog shorter than requested duration of %s, currently %s.", minOplogWindowTime, oplogDuration) + waitTime := float64(m.config.minOplogWindow) - oplogDuration.Seconds() + waitTime *= 1.15 + if waitTime < 600 { + waitTime = 600 + } + return waitTime, nil + } + return 0, nil +} + +func (m *mongoInstance) getOplogCollection() *mongo.Collection { + return m.client.Database("local").Collection("oplog.rs") +} + +func (m *mongoInstance) getAdminDB() *mongo.Database { + return m.client.Database("admin") +} + +func (m *mongoInstance) getOplogDuration(ctx context.Context) (time.Duration, error) { + type MongoMetaData struct { + Wall time.Time `json:"wall"` + } + if oplogC := m.getOplogCollection(); oplogC != nil { + var oldest MongoMetaData + if err := oplogC.FindOne( + ctx, + bson.M{"wall": bson.M{"$exists": true}}, + options.FindOne().SetSort(bson.M{"$natural": 1})).Decode(&oldest); err != nil { + return 0, err + } + + var newest MongoMetaData + if err := oplogC.FindOne( + ctx, + bson.M{"wall": bson.M{"$exists": true}}, + options.FindOne().SetSort(bson.M{"$natural": -1})).Decode(&newest); err != nil { + return 0, err + } + oplogDuration := newest.Wall.Sub(oldest.Wall) + return oplogDuration, nil + } + log.Println("Not clustered, not retrieving oplog duration.") + oplogDuration := time.Duration(m.config.minOplogWindow+1) * time.Second + return oplogDuration, nil +} diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index d9b136e7d7..76e9e182dd 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -113,7 +113,6 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s delete(updatedObject, "bolus") } if schedules := updatedObject["sleepSchedules"]; schedules != nil { - // NOTE: this is to fix sleepSchedules so they are in the required map format scheduleNames := map[int]string{0: "1", 1: "2"} sleepScheduleMap := map[string]interface{}{} From 0cc6b641e2746d26b54c89bc2d639e58b123275e Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 21 Mar 2024 15:14:36 +1300 Subject: [PATCH 275/413] make internal --- .../20231128_jellyfish_migration/utils/data_migration.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go index 3e275a55ca..d518d9a9b9 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration.go @@ -215,7 +215,7 @@ func (m *DataMigration) Execute( return nil } -func (d UpdateData) GetMongoUpdates(rollback bool, rollbackSectionName string) []mongo.WriteModel { +func (d UpdateData) getMongoUpdates(rollback bool, rollbackSectionName string) []mongo.WriteModel { updates := []mongo.WriteModel{} for _, u := range d.Apply { updateOp := mongo.NewUpdateOneModel() @@ -236,7 +236,7 @@ func (d UpdateData) GetMongoUpdates(rollback bool, rollbackSectionName string) [ func (m *DataMigration) SetUpdates(data UpdateData) { m.groupedDiffs[data.ItemType] = append(m.groupedDiffs[data.ItemType], data) - m.updates = append(m.updates, data.GetMongoUpdates(m.config.rollback, m.config.rollbackSectionName)...) + m.updates = append(m.updates, data.getMongoUpdates(m.config.rollback, m.config.rollbackSectionName)...) } func (m *DataMigration) ResetUpdates() { From af0214db91d49cdd7df4d2263e81ae64d4b00731 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 26 Mar 2024 13:30:03 +1300 Subject: [PATCH 276/413] not nil or empty --- .../20231128_jellyfish_migration/utils/jellyfish_data.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go b/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go index e3abdd50ed..0c2fcdadb4 100644 --- a/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go +++ b/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go @@ -12,13 +12,13 @@ import ( ) func commonQuery(selector bson.M, userID *string, lastFetchedID *string) { - if userID != nil { + if userID != nil && *userID != "" { log.Printf("fetching for user %s", *userID) selector["_userId"] = *userID } idNotObjectID := bson.M{"$not": bson.M{"$type": "objectId"}} - if lastFetchedID != nil { + if lastFetchedID != nil && *lastFetchedID != "" { selector["$and"] = []interface{}{ bson.M{"_id": bson.M{"$gt": *lastFetchedID}}, bson.M{"_id": idNotObjectID}, From 54d6e1618884f560ddd45de2732a2a856e611d73 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 26 Mar 2024 13:53:27 +1300 Subject: [PATCH 277/413] ensure all config is set --- .../20231128_jellyfish_migration/utils/data_migration.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go index d518d9a9b9..540205c5c1 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration.go @@ -84,6 +84,9 @@ func NewDataMigrationConfig(dryRun *bool, stopOnErr *bool, rollback *bool, rollb if rollbackSectionName != nil { cfg.SetRollbackSectionName(*rollbackSectionName) } + if writeToDisk != nil { + cfg.SetWriteToDisk(*writeToDisk) + } if cap != nil && *cap > 0 { cfg.cap = cap log.Printf("capped at %d items", *cfg.cap) @@ -145,6 +148,8 @@ func NewMigration(ctx context.Context, config *DataMigrationConfig, checker Mong return nil, err } + log.Printf("running with config %#v", *config) + m := &DataMigration{ ctx: ctx, dataC: dataC, From 52226ec5a59eadb5f6bba153d6b774e617eec439 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 26 Mar 2024 21:35:50 +1300 Subject: [PATCH 278/413] reset data if not writing to disk --- .../utils/data_migration.go | 74 +++++++++---------- 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go index 540205c5c1..a2c453bb04 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration.go @@ -148,8 +148,6 @@ func NewMigration(ctx context.Context, config *DataMigrationConfig, checker Mong return nil, err } - log.Printf("running with config %#v", *config) - m := &DataMigration{ ctx: ctx, dataC: dataC, @@ -301,6 +299,7 @@ func (m *DataMigration) capReached() bool { stats := m.GetStats() percent := (float64(stats.Fetched) * float64(100)) / float64(*m.config.cap) + log.Printf("processed %.0f %% of %d records and applied %d changes", percent, *m.config.cap, stats.Applied) if *m.config.cap <= stats.Applied || *m.config.cap <= stats.Fetched { @@ -320,62 +319,59 @@ func (c MigrationStats) report() { } func (m *DataMigration) writeErrors(groupLimit *int) { - if m.config.writeToDisk { - for group, errors := range m.groupedErrors { - if groupLimit != nil { - if len(errors) < *groupLimit { - continue - } + if !m.config.writeToDisk { + m.groupedErrors = map[string][]ErrorData{} + } + for group, errors := range m.groupedErrors { + if groupLimit != nil { + if len(errors) < *groupLimit { + continue } - f, err := createFile("error", group, "%s.log") + } + f, err := createFile("error", group, "%s.log") + if err != nil { + log.Println(err) + os.Exit(1) + } + defer f.Close() + for _, data := range errors { + errJSON, err := json.Marshal(data) if err != nil { log.Println(err) os.Exit(1) } - defer f.Close() - for _, data := range errors { - errJSON, err := json.Marshal(data) - if err != nil { - log.Println(err) - os.Exit(1) - } - f.WriteString(string(errJSON) + "\n") - } - m.groupedErrors[group] = []ErrorData{} + f.WriteString(string(errJSON) + "\n") } + m.groupedErrors[group] = []ErrorData{} } } func (m *DataMigration) writeAudit(groupLimit *int) { - - if !m.config.dryRun { + if !m.config.writeToDisk || !m.config.dryRun { m.groupedDiffs = map[string][]UpdateData{} return } - if m.config.writeToDisk { - - for group, diffs := range m.groupedDiffs { - if groupLimit != nil { - if len(diffs) < *groupLimit { - continue - } + for group, diffs := range m.groupedDiffs { + if groupLimit != nil { + if len(diffs) < *groupLimit { + continue } - f, err := createFile("audit", group, "%s.json") + } + f, err := createFile("audit", group, "%s.json") + if err != nil { + log.Println(err) + os.Exit(1) + } + defer f.Close() + for _, data := range diffs { + diffJSON, err := json.Marshal(data) if err != nil { log.Println(err) os.Exit(1) } - defer f.Close() - for _, data := range diffs { - diffJSON, err := json.Marshal(data) - if err != nil { - log.Println(err) - os.Exit(1) - } - f.WriteString(string(diffJSON) + "\n") - } - m.groupedDiffs[group] = []UpdateData{} + f.WriteString(string(diffJSON) + "\n") } + m.groupedDiffs[group] = []UpdateData{} } } From 329a62cc60957456a1c028ffaeb80215c686fe26 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 26 Mar 2024 21:55:56 +1300 Subject: [PATCH 279/413] write as we go --- migrations/20231128_jellyfish_migration/utils/data_migration.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go index a2c453bb04..aa552ffdea 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration.go @@ -211,6 +211,8 @@ func (m *DataMigration) Execute( if m.capReached() { break } + m.writeErrors(nil) + m.writeAudit(nil) } m.GetStats().report() m.writeErrors(nil) From 8b4bcd8a6208af76c16257c6a2d3a44cfcc81bb2 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 26 Mar 2024 22:13:24 +1300 Subject: [PATCH 280/413] don't persist raw data --- .../20231128_jellyfish_migration/utils/data_migration.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go index aa552ffdea..7d9f5ca8eb 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration.go @@ -122,9 +122,9 @@ type DataMigration struct { updates []mongo.WriteModel groupedDiffs map[string][]UpdateData groupedErrors groupedErrors - rawData []bson.M errorsCount int updatedCount int + fetchedCount int lastUpdatedId string startedAt time.Time mongoInstanceChecker MongoInstanceCheck @@ -154,11 +154,11 @@ func NewMigration(ctx context.Context, config *DataMigrationConfig, checker Mong mongoInstanceChecker: checker, config: config, updates: []mongo.WriteModel{}, - rawData: []bson.M{}, groupedErrors: groupedErrors{}, groupedDiffs: map[string][]UpdateData{}, errorsCount: 0, updatedCount: 0, + fetchedCount: 0, startedAt: time.Now(), } if lastID != nil { @@ -258,13 +258,13 @@ func (m *DataMigration) SetLastProcessed(lastID string) { } func (m *DataMigration) SetFetched(raw []bson.M) { - m.rawData = append(m.rawData, raw...) + m.fetchedCount += len(raw) } func (m *DataMigration) GetStats() MigrationStats { return MigrationStats{ Errored: m.errorsCount, - Fetched: len(m.rawData), + Fetched: m.fetchedCount, ToApply: len(m.updates), Applied: m.updatedCount, Elapsed: time.Since(m.startedAt).Truncate(time.Millisecond), From 0bafed4dfdcbddee6060c6793adb0c8bf8fb335b Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 27 Mar 2024 12:07:41 +1300 Subject: [PATCH 281/413] cleanup --- .../utils/data_migration.go | 45 +++++++++---------- .../utils/jellyfish_data.go | 6 +-- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go index 7d9f5ca8eb..c63032472b 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration.go @@ -207,8 +207,8 @@ func (m *DataMigration) Execute( m.writeErrors(nil) return err } - m.updatedCount += count - if m.capReached() { + m.updatesApplied(count) + if m.completeUpdates() { break } m.writeErrors(nil) @@ -244,8 +244,25 @@ func (m *DataMigration) SetUpdates(data UpdateData) { m.updates = append(m.updates, data.getMongoUpdates(m.config.rollback, m.config.rollbackSectionName)...) } -func (m *DataMigration) ResetUpdates() { +func (m *DataMigration) updatesApplied(updatedCount int) { m.updates = []mongo.WriteModel{} + m.updatedCount += updatedCount +} + +func (m *DataMigration) completeUpdates() bool { + if m.config.cap != nil { + stats := m.GetStats() + + percent := (float64(stats.Fetched) * float64(100)) / float64(*m.config.cap) + + log.Printf("processed %.0f %% of %d records and applied %d changes", percent, *m.config.cap, stats.Applied) + + if *m.config.cap <= stats.Applied || *m.config.cap <= stats.Fetched { + log.Printf("cap [%d] updates applied [%d] fetched [%d]", *m.config.cap, stats.Applied, stats.Fetched) + return true + } + } + return false } func (m *DataMigration) GetUpdates() []mongo.WriteModel { @@ -278,15 +295,13 @@ func (m *DataMigration) GetLastID() string { func (m *DataMigration) OnError(data ErrorData) { m.errorsCount++ m.groupedErrors[data.ItemType] = append(m.groupedErrors[data.ItemType], data) - var errFormat = "[_id=%s] %s %s\n" - if m.config.stopOnErr { - log.Printf(errFormat, data.ItemID, data.Msg, data.Error.Error()) + log.Printf("[_id=%s] %s %s\n", data.ItemID, data.Msg, data.Error.Error()) os.Exit(1) } } -func (m *DataMigration) UpdateChecks() error { +func (m *DataMigration) CheckMongoInstance() error { if err := m.mongoInstanceChecker.BlockUntilDBReady(m.GetCtx()); err != nil { return err } @@ -296,22 +311,6 @@ func (m *DataMigration) UpdateChecks() error { return nil } -func (m *DataMigration) capReached() bool { - if m.config.cap != nil { - stats := m.GetStats() - - percent := (float64(stats.Fetched) * float64(100)) / float64(*m.config.cap) - - log.Printf("processed %.0f %% of %d records and applied %d changes", percent, *m.config.cap, stats.Applied) - - if *m.config.cap <= stats.Applied || *m.config.cap <= stats.Fetched { - log.Printf("cap [%d] updates applied [%d] fetched [%d]", *m.config.cap, stats.Applied, stats.Fetched) - return true - } - } - return false -} - func (c MigrationStats) report() { if c.Applied == 0 && c.Fetched > 0 { log.Printf("elapsed [%s] for [%d] items fetched with [%d] errors\n", c.Elapsed, c.Fetched, c.Errored) diff --git a/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go b/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go index 0c2fcdadb4..b82a509368 100644 --- a/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go +++ b/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go @@ -122,7 +122,7 @@ var JellyfishDataUpdatesFn = func(m *DataMigration) (int, error) { if dataC == nil { return 0, errors.New("missing required collection to write updates to") } - if len(m.GetUpdates()) == 0 { + if len(updates) == 0 { return 0, nil } @@ -140,10 +140,9 @@ var JellyfishDataUpdatesFn = func(m *DataMigration) (int, error) { writtenCount := 0 for _, batch := range getBatches(int(*settings.WriteBatchSize)) { - if err := m.UpdateChecks(); err != nil { + if err := m.CheckMongoInstance(); err != nil { return writtenCount, err } - if settings.DryRun { writtenCount += len(batch) continue @@ -155,6 +154,5 @@ var JellyfishDataUpdatesFn = func(m *DataMigration) (int, error) { } writtenCount += int(results.ModifiedCount) } - m.ResetUpdates() return writtenCount, nil } From 5e72371fe14adf60d8b662ceda67669fcd149d6b Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Apr 2024 10:01:46 +1300 Subject: [PATCH 282/413] allow to build error summary --- .../error_summary.sh | 10 ++++++++++ .../search_errors.sh | 18 ------------------ 2 files changed, 10 insertions(+), 18 deletions(-) create mode 100644 migrations/20231128_jellyfish_migration/error_summary.sh delete mode 100644 migrations/20231128_jellyfish_migration/search_errors.sh diff --git a/migrations/20231128_jellyfish_migration/error_summary.sh b/migrations/20231128_jellyfish_migration/error_summary.sh new file mode 100644 index 0000000000..53b9e3788a --- /dev/null +++ b/migrations/20231128_jellyfish_migration/error_summary.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +INPUT_FILE=$1 + +echo "input_file: $INPUT_FILE" +echo $INPUT_FILE | cut -d'.' -f1 | read OUTPUT + +echo "output_file: ${OUTPUT}_summary.log" + +cat $INPUT_FILE | jq '.error.detail' | sort | uniq -c | sort -nr >"${OUTPUT}_summary.log" diff --git a/migrations/20231128_jellyfish_migration/search_errors.sh b/migrations/20231128_jellyfish_migration/search_errors.sh deleted file mode 100644 index bda290a6e0..0000000000 --- a/migrations/20231128_jellyfish_migration/search_errors.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -INPUT_FILE=$1 -OUTPUT_FILE=$2 -EXCLUDE_TXT=$3 -TMP_FILE=tmp.json - -echo "input_file: $INPUT_FILE" -echo "output_file: $OUTPUT_FILE" -echo "exclude error code: $EXCLUDE_TXT" - -jq -cnr '(reduce inputs as $line ([]; . + [$line]))' $INPUT_FILE >$TMP_FILE - -if [[ -z "$EXCLUDE_TXT" ]]; then - jq -c "map(.)|unique_by(.error.detail)|.[]|{"id":._id,"detail":.error.detail,"code":.error.code, "source":.error.source}" $TMP_FILE >$OUTPUT_FILE -else - jq -c "map(.)|unique_by(.error.detail)|.[]|select(.error.detail!=null)|select(.error.detail|contains(\"$EXCLUDE_TXT\")|not)|.[]|{"id":._id,"detail":.error.detail,"code":.error.code, "source":.error.source}" $TMP_FILE >$OUTPUT_FILE -fi From 5a4a210d9b537f1d845afc1bb5518ddd28d0ed9c Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Apr 2024 11:18:37 +1300 Subject: [PATCH 283/413] fixes to generate log summary --- migrations/20231128_jellyfish_migration/error_summary.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) mode change 100644 => 100755 migrations/20231128_jellyfish_migration/error_summary.sh diff --git a/migrations/20231128_jellyfish_migration/error_summary.sh b/migrations/20231128_jellyfish_migration/error_summary.sh old mode 100644 new mode 100755 index 53b9e3788a..5824351c57 --- a/migrations/20231128_jellyfish_migration/error_summary.sh +++ b/migrations/20231128_jellyfish_migration/error_summary.sh @@ -3,8 +3,9 @@ INPUT_FILE=$1 echo "input_file: $INPUT_FILE" -echo $INPUT_FILE | cut -d'.' -f1 | read OUTPUT +parts=($(echo $INPUT_FILE | cut -d '.' -f1)) -echo "output_file: ${OUTPUT}_summary.log" +OUTPUT_FILE="${parts[0]}_summary.log" +echo "output_file: $OUTPUT_FILE" -cat $INPUT_FILE | jq '.error.detail' | sort | uniq -c | sort -nr >"${OUTPUT}_summary.log" +cat $INPUT_FILE | jq '.error.detail' | sort | uniq -c | sort -nr >$OUTPUT_FILE From d43e44cad0fcefd5c4f68087f3842d828b6f2263 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Apr 2024 12:28:07 +1300 Subject: [PATCH 284/413] roll log file every 6 hours --- .../20231128_jellyfish_migration/utils/data_migration.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go index c63032472b..ce1f3229c1 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration.go @@ -391,6 +391,7 @@ func (m *DataMigration) writeLastProcessed(itemID string) { } func createFile(fileType string, dataGroup string, logName string) (*os.File, error) { + var err error if fileType == "" { errors.Join(err, errors.New("missing file type")) @@ -404,12 +405,15 @@ func createFile(fileType string, dataGroup string, logName string) (*os.File, er if err != nil { return nil, err } + logName = fmt.Sprintf(logName, dataGroup) - logPath := filepath.Join(".", fileType) + dateContainer := time.Now().Round(6 * time.Hour).Format(time.DateTime) + logPath := filepath.Join(".", dateContainer, fileType) err = os.MkdirAll(logPath, os.ModePerm) if err != nil { return nil, err } + return os.OpenFile(logPath+"/"+logName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) } From 582b55f3b461ff2d8fa9ee8974792d41cc5c2f7f Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Apr 2024 12:55:41 +1300 Subject: [PATCH 285/413] format dateContainer for logs --- .../20231128_jellyfish_migration/utils/data_migration.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go index ce1f3229c1..2231e42e68 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration.go @@ -407,8 +407,8 @@ func createFile(fileType string, dataGroup string, logName string) (*os.File, er } logName = fmt.Sprintf(logName, dataGroup) - dateContainer := time.Now().Round(6 * time.Hour).Format(time.DateTime) - logPath := filepath.Join(".", dateContainer, fileType) + dateContainer := time.Now().Round(6 * time.Hour).Format("2006-01-02T15-04-05") + logPath := filepath.Join(".", fileType, dateContainer) err = os.MkdirAll(logPath, os.ModePerm) if err != nil { From 8ebb807151bf2ada14997b345072574550a37c11 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Apr 2024 12:57:37 +1300 Subject: [PATCH 286/413] fix err check --- .../20231128_jellyfish_migration/utils/data_migration.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go index 2231e42e68..73eef50ed2 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration.go @@ -394,13 +394,13 @@ func createFile(fileType string, dataGroup string, logName string) (*os.File, er var err error if fileType == "" { - errors.Join(err, errors.New("missing file type")) + err = errors.Join(err, errors.New("missing file type")) } if dataGroup == "" { - errors.Join(err, errors.New("missing data group")) + err = errors.Join(err, errors.New("missing data group")) } if logName == "" { - errors.Join(err, errors.New("missing log group")) + err = errors.Join(err, errors.New("missing log group")) } if err != nil { return nil, err From 5dcb098805cf7290f6d4c6c6de17f455f2c8f054 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Apr 2024 14:14:06 +1300 Subject: [PATCH 287/413] report run details --- .../jellyfish_migration.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index b02d8f2d21..0866c0f583 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -58,6 +58,19 @@ func NewJellyfishMigration(ctx context.Context) *Migration { } } +func (c *config) report() string { + return fmt.Sprintf("MIGRATION DETAILS:\n\nPROCESSED CAP [%d]\nROLLBACK? [%t]\nDRY_RUN? [%t]\nSTOP ON ERROR? [%t]\nLAST ID [%s]\nQUERY [SIZE=%d LIMIT=%d]\nUSER ID[%s]", + c.cap, + c.dryRun, + c.rollback, + c.stopOnErr, + c.lastUpdatedId, + c.queryBatchSize, + c.queryLimit, + c.userID, + ) +} + func (m *Migration) RunAndExit() { if err := m.Initialize(); err != nil { os.Exit(1) @@ -91,6 +104,9 @@ func (m *Migration) RunAndExit() { m.client.Database("data").Collection("deviceData"), &m.config.lastUpdatedId, ) + + log.Printf("%s", m.config.report()) + if err != nil { return fmt.Errorf("unable to create migration utils : %w", err) } From b34056d21b3c474e8e20c3f137a8f5967e135cd0 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Apr 2024 14:46:27 +1300 Subject: [PATCH 288/413] show query and config --- .../jellyfish_migration.go | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 0866c0f583..3fd2764a82 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -59,16 +59,16 @@ func NewJellyfishMigration(ctx context.Context) *Migration { } func (c *config) report() string { - return fmt.Sprintf("MIGRATION DETAILS:\n\nPROCESSED CAP [%d]\nROLLBACK? [%t]\nDRY_RUN? [%t]\nSTOP ON ERROR? [%t]\nLAST ID [%s]\nQUERY [SIZE=%d LIMIT=%d]\nUSER ID[%s]", - c.cap, - c.dryRun, - c.rollback, - c.stopOnErr, - c.lastUpdatedId, - c.queryBatchSize, - c.queryLimit, - c.userID, - ) + details := "\nMIGRATION DETAILS:\n" + details += fmt.Sprintf("- CAP\t[%d]\n", c.cap) + details += fmt.Sprintf("- AUDIT? \t[%t]\n", c.dryRun) + details += fmt.Sprintf("- ROLLBACK\t[%t]\n", c.rollback) + details += fmt.Sprintf("- STOP ON ERROR\t[%t]\n", c.stopOnErr) + details += fmt.Sprintf("- LAST PROCESSED ID\t[%s]\n", c.lastUpdatedId) + details += fmt.Sprintf("- USER ID\t[%s]\n", c.userID) + details += fmt.Sprintf("- QUERY BATCH\t[%d]\n", c.queryBatchSize) + details += fmt.Sprintf("- QUERY LIMIT\t[%d]\n", c.queryLimit) + return details } func (m *Migration) RunAndExit() { @@ -133,6 +133,7 @@ func (m *Migration) RunAndExit() { m.config.queryLimit, ) } + log.Printf("query: %v ", selector) if err := m.migrationUtil.Execute(selector, opt, utils.JellyfishDataQueryFn, utils.JellyfishDataUpdatesFn); err != nil { log.Printf("execute failed: %s", err) return err From cbf581a9aa06abc4034b3027affea29654b75079 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Apr 2024 18:00:26 +1300 Subject: [PATCH 289/413] cleanup settings --- .../jellyfish_migration.go | 47 +++---- .../utils/data_migration.go | 123 +++++++----------- .../utils/data_migration_test.go | 27 ++-- .../utils/jellyfish_data.go | 54 ++++---- .../utils/mongo_instance_check.go | 21 ++- 5 files changed, 114 insertions(+), 158 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 3fd2764a82..cff7e2f24b 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -33,8 +33,8 @@ type config struct { userID string lastUpdatedId string nopPercent int - queryBatchSize int64 - queryLimit int64 + queryBatchSize int + queryLimit int } const DryRunFlag = "dry-run" @@ -60,14 +60,14 @@ func NewJellyfishMigration(ctx context.Context) *Migration { func (c *config) report() string { details := "\nMIGRATION DETAILS:\n" - details += fmt.Sprintf("- CAP\t[%d]\n", c.cap) - details += fmt.Sprintf("- AUDIT? \t[%t]\n", c.dryRun) - details += fmt.Sprintf("- ROLLBACK\t[%t]\n", c.rollback) - details += fmt.Sprintf("- STOP ON ERROR\t[%t]\n", c.stopOnErr) + details += fmt.Sprintf("- CAP\t\t\t[%d]\n", c.cap) + details += fmt.Sprintf("- AUDIT? \t\t[%t]\n", c.dryRun) + details += fmt.Sprintf("- ROLLBACK\t\t[%t]\n", c.rollback) + details += fmt.Sprintf("- STOP ON ERROR\t\t[%t]\n", c.stopOnErr) details += fmt.Sprintf("- LAST PROCESSED ID\t[%s]\n", c.lastUpdatedId) - details += fmt.Sprintf("- USER ID\t[%s]\n", c.userID) - details += fmt.Sprintf("- QUERY BATCH\t[%d]\n", c.queryBatchSize) - details += fmt.Sprintf("- QUERY LIMIT\t[%d]\n", c.queryLimit) + details += fmt.Sprintf("- USER ID\t\t[%s]\n", c.userID) + details += fmt.Sprintf("- QUERY BATCH\t\t[%d]\n", c.queryBatchSize) + details += fmt.Sprintf("- QUERY LIMIT\t\t[%d]\n", c.queryLimit) return details } @@ -92,12 +92,14 @@ func (m *Migration) RunAndExit() { m.migrationUtil, err = utils.NewMigration( m.ctx, - utils.NewDataMigrationConfig( + utils.NewSettings( &m.config.dryRun, &m.config.stopOnErr, &m.config.rollback, &m.config.rollbackSectionName, &m.config.cap, + &m.config.queryBatchSize, + &m.config.queryLimit, pointer.FromBool(true), ), dbChecker, @@ -115,26 +117,7 @@ func (m *Migration) RunAndExit() { log.Printf("prepare failed: %s", err) return err } - lastFetchedID := m.migrationUtil.GetLastID() - - selector, opt := utils.JellyfishDataQuery( - &m.config.userID, - &lastFetchedID, - m.config.queryBatchSize, - m.config.queryLimit, - ) - - if m.config.rollback { - selector, opt = utils.JellyfishDataRollbackQuery( - m.config.rollbackSectionName, - &m.config.userID, - &lastFetchedID, - m.config.queryBatchSize, - m.config.queryLimit, - ) - } - log.Printf("query: %v ", selector) - if err := m.migrationUtil.Execute(selector, opt, utils.JellyfishDataQueryFn, utils.JellyfishDataUpdatesFn); err != nil { + if err := m.migrationUtil.Execute(utils.JellyfishDataQueryFn, utils.JellyfishDataUpdatesFn); err != nil { log.Printf("execute failed: %s", err) return err } @@ -209,14 +192,14 @@ func (m *Migration) Initialize() error { Destination: &m.config.userID, Required: false, }, - cli.Int64Flag{ + cli.IntFlag{ Name: "query-limit", Usage: "max number of items to return", Destination: &m.config.queryLimit, Value: 50000, Required: false, }, - cli.Int64Flag{ + cli.IntFlag{ Name: "query-batch", Usage: "max number of items in each query batch", Destination: &m.config.queryBatchSize, diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go index 73eef50ed2..036c09c321 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration.go @@ -13,7 +13,6 @@ import ( "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" ) type UpdateData struct { @@ -46,79 +45,56 @@ type Settings struct { Rollback bool RollbackSectionName string StopOnErr bool - Cap *int WriteBatchSize *int64 -} + QueryBatchSize int + QueryBatchLimit int -type DataMigrationConfig struct { + capacity *int writeToDisk bool - //apply no changes - dryRun bool - //rollback the changes that have been applied - rollback bool - //name of section with mongo document that stores the original values - rollbackSectionName string - //halt on error - stopOnErr bool - // cap for number of items to migrate - cap *int } -func NewDataMigrationConfig(dryRun *bool, stopOnErr *bool, rollback *bool, rollbackSectionName *string, cap *int, writeToDisk *bool) *DataMigrationConfig { - cfg := &DataMigrationConfig{ +func NewSettings(dryRun *bool, stopOnErr *bool, rollback *bool, rollbackSectionName *string, capacity *int, queryBatch *int, queryLimit *int, writeToDisk *bool) *Settings { + settings := &Settings{ writeToDisk: false, - rollback: true, - rollbackSectionName: "_rollbackMigration", - dryRun: true, - stopOnErr: true, + Rollback: true, + RollbackSectionName: "_rollbackMigration", + DryRun: true, + StopOnErr: true, + QueryBatchSize: 50, + QueryBatchLimit: 100, } if dryRun != nil { - cfg.SetDryRun(*dryRun) + settings.DryRun = *dryRun } if stopOnErr != nil { - cfg.SetStopOnErr(*stopOnErr) + settings.StopOnErr = *stopOnErr } if rollback != nil { - cfg.SetRollback(*rollback) + settings.Rollback = *rollback } if rollbackSectionName != nil { - cfg.SetRollbackSectionName(*rollbackSectionName) + settings.RollbackSectionName = *rollbackSectionName } if writeToDisk != nil { - cfg.SetWriteToDisk(*writeToDisk) + settings.writeToDisk = *writeToDisk } - if cap != nil && *cap > 0 { - cfg.cap = cap - log.Printf("capped at %d items", *cfg.cap) + if queryBatch != nil { + settings.QueryBatchSize = *queryBatch } - return cfg -} - -func (c *DataMigrationConfig) SetDryRun(dryRun bool) *DataMigrationConfig { - c.dryRun = dryRun - return c -} -func (c *DataMigrationConfig) SetStopOnErr(stopOnErr bool) *DataMigrationConfig { - c.stopOnErr = stopOnErr - return c -} -func (c *DataMigrationConfig) SetRollback(rollback bool) *DataMigrationConfig { - c.rollback = rollback - return c -} -func (c *DataMigrationConfig) SetRollbackSectionName(rollbackSectionName string) *DataMigrationConfig { - c.rollbackSectionName = rollbackSectionName - return c -} -func (c *DataMigrationConfig) SetWriteToDisk(writeToDisk bool) *DataMigrationConfig { - c.writeToDisk = writeToDisk - return c + if queryLimit != nil { + settings.QueryBatchLimit = *queryLimit + } + if capacity != nil && *capacity > 0 { + settings.capacity = capacity + log.Printf("capped at %d items", *settings.capacity) + } + return settings } type DataMigration struct { ctx context.Context dataC *mongo.Collection - config *DataMigrationConfig + settings *Settings updates []mongo.WriteModel groupedDiffs map[string][]UpdateData groupedErrors groupedErrors @@ -130,15 +106,15 @@ type DataMigration struct { mongoInstanceChecker MongoInstanceCheck } -type DataMigrationQueryFn func(m *DataMigration, selector bson.M, opts ...*options.FindOptions) bool +type DataMigrationQueryFn func(m *DataMigration) bool type DataMigrationUpdateFn func(m *DataMigration) (int, error) type groupedErrors map[string][]ErrorData -func NewMigration(ctx context.Context, config *DataMigrationConfig, checker MongoInstanceCheck, dataC *mongo.Collection, lastID *string) (*DataMigration, error) { +func NewMigration(ctx context.Context, settings *Settings, checker MongoInstanceCheck, dataC *mongo.Collection, lastID *string) (*DataMigration, error) { var err error - if config == nil { - err = errors.Join(err, errors.New("missing required configuration")) + if settings == nil { + err = errors.Join(err, errors.New("missing required settings")) } if checker == nil { err = errors.Join(err, errors.New("missing required mongo checker")) @@ -152,7 +128,7 @@ func NewMigration(ctx context.Context, config *DataMigrationConfig, checker Mong ctx: ctx, dataC: dataC, mongoInstanceChecker: checker, - config: config, + settings: settings, updates: []mongo.WriteModel{}, groupedErrors: groupedErrors{}, groupedDiffs: map[string][]UpdateData{}, @@ -182,14 +158,8 @@ func (m *DataMigration) GetCtx() context.Context { } func (m *DataMigration) GetSettings() Settings { - return Settings{ - DryRun: m.config.dryRun, - Rollback: m.config.rollback, - RollbackSectionName: m.config.rollbackSectionName, - Cap: m.config.cap, - StopOnErr: m.config.stopOnErr, - WriteBatchSize: m.mongoInstanceChecker.GetWriteBatchSize(), - } + m.settings.WriteBatchSize = m.mongoInstanceChecker.GetWriteBatchSize() + return *m.settings } func (m *DataMigration) GetDataCollection() *mongo.Collection { @@ -197,11 +167,9 @@ func (m *DataMigration) GetDataCollection() *mongo.Collection { } func (m *DataMigration) Execute( - selector bson.M, - selectorOpt *options.FindOptions, queryFn DataMigrationQueryFn, updateFn DataMigrationUpdateFn) error { - for queryFn(m, selector, selectorOpt) { + for queryFn(m) { count, err := updateFn(m) if err != nil { m.writeErrors(nil) @@ -241,7 +209,7 @@ func (d UpdateData) getMongoUpdates(rollback bool, rollbackSectionName string) [ func (m *DataMigration) SetUpdates(data UpdateData) { m.groupedDiffs[data.ItemType] = append(m.groupedDiffs[data.ItemType], data) - m.updates = append(m.updates, data.getMongoUpdates(m.config.rollback, m.config.rollbackSectionName)...) + m.updates = append(m.updates, data.getMongoUpdates(m.settings.Rollback, m.settings.RollbackSectionName)...) } func (m *DataMigration) updatesApplied(updatedCount int) { @@ -250,15 +218,16 @@ func (m *DataMigration) updatesApplied(updatedCount int) { } func (m *DataMigration) completeUpdates() bool { - if m.config.cap != nil { + capacity := m.settings.capacity + if capacity != nil { stats := m.GetStats() - percent := (float64(stats.Fetched) * float64(100)) / float64(*m.config.cap) + percent := (float64(stats.Fetched) * float64(100)) / float64(*capacity) - log.Printf("processed %.0f %% of %d records and applied %d changes", percent, *m.config.cap, stats.Applied) + log.Printf("processed %.0f %% of %d records and applied %d changes", percent, *capacity, stats.Applied) - if *m.config.cap <= stats.Applied || *m.config.cap <= stats.Fetched { - log.Printf("cap [%d] updates applied [%d] fetched [%d]", *m.config.cap, stats.Applied, stats.Fetched) + if *capacity <= stats.Applied || *capacity <= stats.Fetched { + log.Printf("cap [%d] updates applied [%d] fetched [%d]", *capacity, stats.Applied, stats.Fetched) return true } } @@ -295,7 +264,7 @@ func (m *DataMigration) GetLastID() string { func (m *DataMigration) OnError(data ErrorData) { m.errorsCount++ m.groupedErrors[data.ItemType] = append(m.groupedErrors[data.ItemType], data) - if m.config.stopOnErr { + if m.settings.StopOnErr { log.Printf("[_id=%s] %s %s\n", data.ItemID, data.Msg, data.Error.Error()) os.Exit(1) } @@ -320,7 +289,7 @@ func (c MigrationStats) report() { } func (m *DataMigration) writeErrors(groupLimit *int) { - if !m.config.writeToDisk { + if !m.settings.writeToDisk { m.groupedErrors = map[string][]ErrorData{} } for group, errors := range m.groupedErrors { @@ -348,7 +317,7 @@ func (m *DataMigration) writeErrors(groupLimit *int) { } func (m *DataMigration) writeAudit(groupLimit *int) { - if !m.config.writeToDisk || !m.config.dryRun { + if !m.settings.writeToDisk || !m.settings.DryRun { m.groupedDiffs = map[string][]UpdateData{} return } @@ -377,7 +346,7 @@ func (m *DataMigration) writeAudit(groupLimit *int) { } func (m *DataMigration) writeLastProcessed(itemID string) { - if m.config.writeToDisk { + if m.settings.writeToDisk { if strings.TrimSpace(itemID) != "" { f, err := os.Create("./lastProcessedId") if err != nil { diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration_test.go b/migrations/20231128_jellyfish_migration/utils/data_migration_test.go index 13b692fabb..70f6ebeb28 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration_test.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration_test.go @@ -58,27 +58,31 @@ var _ = Describe("back-37", func() { const datumCount = 1000 var store *dataStoreMongo.Store var ctx context.Context - var rollbackConfig *utils.DataMigrationConfig - var migtaionConfig *utils.DataMigrationConfig + var rollbackSettings *utils.Settings + var migrationSettings *utils.Settings BeforeEach(func() { logger := logTest.NewLogger() ctx = platformLog.NewContextWithLogger(context.Background(), logger) testData = test.BulkJellyfishData("test-device-88x89", "test-group-id", "test-user-id-123", datumCount) - rollbackConfig = utils.NewDataMigrationConfig( + rollbackSettings = utils.NewSettings( pointer.FromBool(false), pointer.FromBool(false), pointer.FromBool(true), pointer.FromString("_testRollback"), nil, + pointer.FromInt(50), + pointer.FromInt(100), pointer.FromBool(false), ) - migtaionConfig = utils.NewDataMigrationConfig( + migrationSettings = utils.NewSettings( pointer.FromBool(false), pointer.FromBool(false), pointer.FromBool(false), pointer.FromString("_testRollback"), nil, + pointer.FromInt(50), + pointer.FromInt(100), pointer.FromBool(false), ) var err error @@ -95,7 +99,7 @@ var _ = Describe("back-37", func() { collection := store.GetCollection("testMigration") Expect(setCollectionData(ctx, collection, testData)).To(Succeed()) - migration, err := utils.NewMigration(ctx, migtaionConfig, newMongoInstanceChecker(), collection, nil) + migration, err := utils.NewMigration(ctx, migrationSettings, newMongoInstanceChecker(), collection, nil) Expect(err).To(BeNil()) Expect(testData).ToNot(BeNil()) @@ -103,8 +107,7 @@ var _ = Describe("back-37", func() { allDocs, err := collection.CountDocuments(ctx, bson.D{}) Expect(err).To(BeNil()) Expect(allDocs).To(Equal(int64(datumCount))) - selector, opt := utils.JellyfishDataQuery(nil, nil, 50, 100) - Expect(migration.Execute(selector, opt, utils.JellyfishDataQueryFn, utils.JellyfishDataUpdatesFn)).To(Succeed()) + Expect(migration.Execute(utils.JellyfishDataQueryFn, utils.JellyfishDataUpdatesFn)).To(Succeed()) stats := migration.GetStats() Expect(stats.Errored).To(Equal(0)) Expect(stats.Fetched).To(Equal(datumCount)) @@ -133,7 +136,7 @@ var _ = Describe("back-37", func() { findOptions := options.Find() findOptions.SetSort(bson.D{{Key: "_id", Value: -1}}) - migration, err := utils.NewMigration(ctx, migtaionConfig, newMongoInstanceChecker(), collection, nil) + migration, err := utils.NewMigration(ctx, migrationSettings, newMongoInstanceChecker(), collection, nil) Expect(err).To(BeNil()) Expect(testData).ToNot(BeNil()) @@ -146,8 +149,7 @@ var _ = Describe("back-37", func() { cur.All(ctx, &original) Expect(len(original)).To(Equal(datumCount)) - selector, opt := utils.JellyfishDataQuery(nil, nil, 50, 100) - Expect(migration.Execute(selector, opt, utils.JellyfishDataQueryFn, utils.JellyfishDataUpdatesFn)).To(Succeed()) + Expect(migration.Execute(utils.JellyfishDataQueryFn, utils.JellyfishDataUpdatesFn)).To(Succeed()) cur, err = collection.Find(ctx, bson.D{}, findOptions) Expect(err).To(BeNil()) @@ -155,11 +157,10 @@ var _ = Describe("back-37", func() { cur.All(ctx, &migrated) Expect(len(migrated)).To(Equal(datumCount)) - rollback, err := utils.NewMigration(ctx, rollbackConfig, newMongoInstanceChecker(), collection, nil) + rollback, err := utils.NewMigration(ctx, rollbackSettings, newMongoInstanceChecker(), collection, nil) Expect(err).To(BeNil()) - rollbackSelector, rollbackOpt := utils.JellyfishDataRollbackQuery(rollback.GetSettings().RollbackSectionName, nil, nil, 50, 100) - Expect(rollback.Execute(rollbackSelector, rollbackOpt, utils.JellyfishDataQueryFn, utils.JellyfishDataUpdatesFn)).To(Succeed()) + Expect(rollback.Execute(utils.JellyfishDataQueryFn, utils.JellyfishDataUpdatesFn)).To(Succeed()) cur, err = collection.Find(ctx, bson.D{}, findOptions) Expect(err).To(BeNil()) diff --git a/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go b/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go index b82a509368..4f2d30a591 100644 --- a/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go +++ b/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go @@ -5,13 +5,23 @@ import ( "fmt" "log" + "github.com/tidepool-org/platform/pointer" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) -func commonQuery(selector bson.M, userID *string, lastFetchedID *string) { +func jellyfishQuery(settings Settings, userID *string, lastFetchedID *string) (bson.M, *options.FindOptions) { + selector := bson.M{ + "_deduplicator": bson.M{"$exists": false}, + } + if settings.Rollback { + selector = bson.M{ + settings.RollbackSectionName: bson.M{"$exists": true}, + } + } + if userID != nil && *userID != "" { log.Printf("fetching for user %s", *userID) selector["_userId"] = *userID @@ -26,35 +36,31 @@ func commonQuery(selector bson.M, userID *string, lastFetchedID *string) { } else { selector["_id"] = idNotObjectID } -} -func opt(batchSize int32, queryLimit int64) *options.FindOptions { - return &options.FindOptions{ + bSize := int32(settings.QueryBatchSize) + limit := int64(settings.QueryBatchLimit) + opts := &options.FindOptions{ Sort: bson.M{"_id": 1}, - BatchSize: &batchSize, - Limit: &queryLimit, + BatchSize: &bSize, + Limit: &limit, } -} -func JellyfishDataQuery(userID *string, lastFetchedID *string, batchSize int64, queryLimit int64) (bson.M, *options.FindOptions) { - selector := bson.M{ - "_deduplicator": bson.M{"$exists": false}, - } - commonQuery(selector, userID, lastFetchedID) - return selector, opt(int32(batchSize), queryLimit) + return selector, opts } -func JellyfishDataRollbackQuery(rollbackSectionName string, userID *string, lastFetchedID *string, batchSize int64, queryLimit int64) (bson.M, *options.FindOptions) { - selector := bson.M{ - rollbackSectionName: bson.M{"$exists": true}, - } - commonQuery(selector, userID, lastFetchedID) - return selector, opt(int32(batchSize), queryLimit) -} +var JellyfishDataQueryFn = func(m *DataMigration) bool { + + settings := m.GetSettings() -var JellyfishDataQueryFn = func(m *DataMigration, selector bson.M, opts ...*options.FindOptions) bool { if dataC := m.GetDataCollection(); dataC != nil { - dDataCursor, err := dataC.Find(m.GetCtx(), selector, opts...) + + selector, opts := jellyfishQuery( + settings, + nil, + pointer.FromString(m.GetLastID()), + ) + + dDataCursor, err := dataC.Find(m.GetCtx(), selector, opts) if err != nil { log.Printf("failed to select data: %s", err) return false @@ -72,8 +78,8 @@ var JellyfishDataQueryFn = func(m *DataMigration, selector bson.M, opts ...*opti itemID := fmt.Sprintf("%v", item["_id"]) userID := fmt.Sprintf("%v", item["_userId"]) itemType := fmt.Sprintf("%v", item["type"]) - if m.GetSettings().Rollback { - if rollback, ok := item[m.GetSettings().RollbackSectionName].(primitive.A); ok { + if settings.Rollback { + if rollback, ok := item[settings.RollbackSectionName].(primitive.A); ok { cmds := []bson.M{} for _, cmd := range rollback { if cmd, ok := cmd.(bson.M); ok { diff --git a/migrations/20231128_jellyfish_migration/utils/mongo_instance_check.go b/migrations/20231128_jellyfish_migration/utils/mongo_instance_check.go index 1c7986c69c..332411137a 100644 --- a/migrations/20231128_jellyfish_migration/utils/mongo_instance_check.go +++ b/migrations/20231128_jellyfish_migration/utils/mongo_instance_check.go @@ -106,7 +106,6 @@ func (m *mongoInstance) SetWriteBatchSize(ctx context.Context) error { } func (m *mongoInstance) CheckFreeSpace(ctx context.Context, dataC *mongo.Collection) error { - // pass in config and mongo collection being migrated if dataC == nil { return errors.New("missing required mongo data collection") } @@ -116,18 +115,16 @@ func (m *mongoInstance) CheckFreeSpace(ctx context.Context, dataC *mongo.Collect FsUsedSize int `json:"fsUsedSize"` } var metaData MongoMetaData - if dataC != nil { - if err := dataC.Database().RunCommand(ctx, bson.M{"dbStats": 1}).Decode(&metaData); err != nil { - return err - } - bytesFree := metaData.FsTotalSize - metaData.FsUsedSize - percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) - if m.config.minFreePercent > percentFree { - return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) - } - return nil + + if err := dataC.Database().RunCommand(ctx, bson.M{"dbStats": 1}).Decode(&metaData); err != nil { + return err } - return errors.New("could not get deviceData database") + bytesFree := metaData.FsTotalSize - metaData.FsUsedSize + percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) + if m.config.minFreePercent > percentFree { + return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) + } + return nil } func (m *mongoInstance) BlockUntilDBReady(ctx context.Context) error { From f6770c0eb49066041ecbe8d17277c7fe5a9c4be1 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 4 Apr 2024 10:31:46 +1300 Subject: [PATCH 290/413] linting --- .../jellyfish_migration.go | 8 ++++---- .../utils/data_migration.go | 10 +++++----- .../utils/jellyfish_data.go | 3 ++- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index cff7e2f24b..7bb9679846 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -31,7 +31,7 @@ type config struct { rollback bool rollbackSectionName string userID string - lastUpdatedId string + lastUpdatedID string nopPercent int queryBatchSize int queryLimit int @@ -64,7 +64,7 @@ func (c *config) report() string { details += fmt.Sprintf("- AUDIT? \t\t[%t]\n", c.dryRun) details += fmt.Sprintf("- ROLLBACK\t\t[%t]\n", c.rollback) details += fmt.Sprintf("- STOP ON ERROR\t\t[%t]\n", c.stopOnErr) - details += fmt.Sprintf("- LAST PROCESSED ID\t[%s]\n", c.lastUpdatedId) + details += fmt.Sprintf("- LAST PROCESSED ID\t[%s]\n", c.lastUpdatedID) details += fmt.Sprintf("- USER ID\t\t[%s]\n", c.userID) details += fmt.Sprintf("- QUERY BATCH\t\t[%d]\n", c.queryBatchSize) details += fmt.Sprintf("- QUERY LIMIT\t\t[%d]\n", c.queryLimit) @@ -104,7 +104,7 @@ func (m *Migration) RunAndExit() { ), dbChecker, m.client.Database("data").Collection("deviceData"), - &m.config.lastUpdatedId, + &m.config.lastUpdatedID, ) log.Printf("%s", m.config.report()) @@ -181,7 +181,7 @@ func (m *Migration) Initialize() error { cli.StringFlag{ Name: "datum-id", Usage: "id of last datum updated", - Destination: &m.config.lastUpdatedId, + Destination: &m.config.lastUpdatedID, Required: false, //id of last datum updated read and written to file `lastProcessedId` FilePath: "./lastProcessedId", diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go index 036c09c321..39def887be 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration.go @@ -101,7 +101,7 @@ type DataMigration struct { errorsCount int updatedCount int fetchedCount int - lastUpdatedId string + lastUpdatedID string startedAt time.Time mongoInstanceChecker MongoInstanceCheck } @@ -138,7 +138,7 @@ func NewMigration(ctx context.Context, settings *Settings, checker MongoInstance startedAt: time.Now(), } if lastID != nil { - m.lastUpdatedId = *lastID + m.lastUpdatedID = *lastID } return m, nil } @@ -239,8 +239,8 @@ func (m *DataMigration) GetUpdates() []mongo.WriteModel { } func (m *DataMigration) SetLastProcessed(lastID string) { - m.lastUpdatedId = lastID - m.writeLastProcessed(m.lastUpdatedId) + m.lastUpdatedID = lastID + m.writeLastProcessed(m.lastUpdatedID) } func (m *DataMigration) SetFetched(raw []bson.M) { @@ -258,7 +258,7 @@ func (m *DataMigration) GetStats() MigrationStats { } func (m *DataMigration) GetLastID() string { - return m.lastUpdatedId + return m.lastUpdatedID } func (m *DataMigration) OnError(data ErrorData) { diff --git a/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go b/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go index 4f2d30a591..a42e37a1e6 100644 --- a/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go +++ b/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go @@ -5,11 +5,12 @@ import ( "fmt" "log" - "github.com/tidepool-org/platform/pointer" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" + + "github.com/tidepool-org/platform/pointer" ) func jellyfishQuery(settings Settings, userID *string, lastFetchedID *string) (bson.M, *options.FindOptions) { From cbc0f1e276bf6985f5feb933b1f3a9797274e401 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 4 Apr 2024 10:46:07 +1300 Subject: [PATCH 291/413] optional splitting of the logs --- .../utils/data_migration.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go index 39def887be..f47c89563e 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration.go @@ -51,11 +51,13 @@ type Settings struct { capacity *int writeToDisk bool + splitLogs bool } func NewSettings(dryRun *bool, stopOnErr *bool, rollback *bool, rollbackSectionName *string, capacity *int, queryBatch *int, queryLimit *int, writeToDisk *bool) *Settings { settings := &Settings{ writeToDisk: false, + splitLogs: false, Rollback: true, RollbackSectionName: "_rollbackMigration", DryRun: true, @@ -298,7 +300,7 @@ func (m *DataMigration) writeErrors(groupLimit *int) { continue } } - f, err := createFile("error", group, "%s.log") + f, err := m.createFile("error", group, "%s.log") if err != nil { log.Println(err) os.Exit(1) @@ -327,7 +329,7 @@ func (m *DataMigration) writeAudit(groupLimit *int) { continue } } - f, err := createFile("audit", group, "%s.json") + f, err := m.createFile("audit", group, "%s.json") if err != nil { log.Println(err) os.Exit(1) @@ -359,7 +361,7 @@ func (m *DataMigration) writeLastProcessed(itemID string) { } } -func createFile(fileType string, dataGroup string, logName string) (*os.File, error) { +func (m *DataMigration) createFile(fileType string, dataGroup string, logName string) (*os.File, error) { var err error if fileType == "" { @@ -376,8 +378,11 @@ func createFile(fileType string, dataGroup string, logName string) (*os.File, er } logName = fmt.Sprintf(logName, dataGroup) - dateContainer := time.Now().Round(6 * time.Hour).Format("2006-01-02T15-04-05") - logPath := filepath.Join(".", fileType, dateContainer) + logPath := filepath.Join(".", fileType) + if m.settings.splitLogs { + dateContainer := time.Now().Round(6 * time.Hour).Format("2006-01-02T15-04-05") + logPath = filepath.Join(".", fileType, dateContainer) + } err = os.MkdirAll(logPath, os.ModePerm) if err != nil { From 45b4a57b03baf3fd49e9c7002957d06ce2d046a7 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 4 Apr 2024 11:39:19 +1300 Subject: [PATCH 292/413] remove log splitting - will just ensure disk space --- .../20231128_jellyfish_migration/utils/data_migration.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go index f47c89563e..71acc16c37 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration.go @@ -51,13 +51,11 @@ type Settings struct { capacity *int writeToDisk bool - splitLogs bool } func NewSettings(dryRun *bool, stopOnErr *bool, rollback *bool, rollbackSectionName *string, capacity *int, queryBatch *int, queryLimit *int, writeToDisk *bool) *Settings { settings := &Settings{ writeToDisk: false, - splitLogs: false, Rollback: true, RollbackSectionName: "_rollbackMigration", DryRun: true, @@ -379,11 +377,6 @@ func (m *DataMigration) createFile(fileType string, dataGroup string, logName st logName = fmt.Sprintf(logName, dataGroup) logPath := filepath.Join(".", fileType) - if m.settings.splitLogs { - dateContainer := time.Now().Round(6 * time.Hour).Format("2006-01-02T15-04-05") - logPath = filepath.Join(".", fileType, dateContainer) - } - err = os.MkdirAll(logPath, os.ModePerm) if err != nil { return nil, err From b34ec129fac9dd771d8c4998a92e0231b8ebaabe Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 9 Apr 2024 17:34:54 +1200 Subject: [PATCH 293/413] cleanup cbg parsing of unused fields --- migrations/20231128_jellyfish_migration/utils/utils.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 76e9e182dd..e42defdf34 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -282,6 +282,8 @@ func (b *builder) buildDatum(obj map[string]interface{}) error { switch b.datumType { case continuous.Type: validator.String("subType", parser.String("subType")) + validator.String("jsDate", parser.String("jsDate")) + validator.Int("index", parser.Int("index")) case bolus.Type: validator.String("deliveryContext", parser.String("deliveryContext")) case basal.Type: From e1c1e652d5579bfd0ea0c563ce610f8f6dd732bc Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 10 Apr 2024 21:49:22 +1200 Subject: [PATCH 294/413] updates for drilling into specific details --- .../error_summary.sh | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/error_summary.sh b/migrations/20231128_jellyfish_migration/error_summary.sh index 5824351c57..8f18656c28 100755 --- a/migrations/20231128_jellyfish_migration/error_summary.sh +++ b/migrations/20231128_jellyfish_migration/error_summary.sh @@ -1,11 +1,21 @@ #!/bin/bash INPUT_FILE=$1 +FIND_VAL=$2 echo "input_file: $INPUT_FILE" parts=($(echo $INPUT_FILE | cut -d '.' -f1)) -OUTPUT_FILE="${parts[0]}_summary.log" -echo "output_file: $OUTPUT_FILE" - -cat $INPUT_FILE | jq '.error.detail' | sort | uniq -c | sort -nr >$OUTPUT_FILE +if [[ -z "$FIND_VAL" ]]; then + OUTPUT_FILE="${parts[0]}_summary.log" + echo "output_file: $OUTPUT_FILE" + cat $INPUT_FILE | jq '.error.detail // .error.errors[]?.detail' | sort | uniq -c | sort -nr >$OUTPUT_FILE +else + OUTPUT_FILE="${parts[0]}_detail.log" + echo "output_file: $OUTPUT_FILE" + cat $INPUT_FILE | jq -c "select(.error.detail == \"$FIND_VAL\") // select(.error.errors[]?.detail == \"$FIND_VAL\") \ + | if .error.code != null then \ + { id:._id, error: .error.code, detail: .error.detail, source: .error.source } else \ + { id:._id, source: .error.errors[].source } end \ + " >$OUTPUT_FILE +fi From be287f9b544aac195d05d769b5e89e7d9e79d318 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 16 Apr 2024 15:16:41 +1200 Subject: [PATCH 295/413] fix and test for cgmSettings --- .../utils/utils.go | 6 ++- .../utils/utils_test.go | 48 +++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index e42defdf34..08ee95151a 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -173,18 +173,20 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s case cgm.Type: units := fmt.Sprintf("%v", updatedObject["units"]) if units == glucose.MmolL || units == glucose.Mmoll { - if lowAlerts, ok := updatedObject["lowAlerts"].(bson.M); ok { + if lowAlerts, ok := updatedObject["lowAlerts"].(map[string]interface{}); ok { if bgVal, ok := lowAlerts["level"].(float64); ok { lowAlerts["level"] = getBGValuePrecision(bgVal) updatedObject["lowAlerts"] = lowAlerts } } - if highAlerts, ok := updatedObject["highAlerts"].(bson.M); ok { + if highAlerts, ok := updatedObject["highAlerts"].(map[string]interface{}); ok { if bgVal, ok := highAlerts["level"].(float64); ok { highAlerts["level"] = getBGValuePrecision(bgVal) updatedObject["highAlerts"] = highAlerts } } + // NOTE `rateOfChangeAlerts` not included as the fallRate.rate and riseRate.rate maintain orginal + // precicsion see platform/data/types/settings/cgm/rate_alert_DEPRECATED.go RateDEPRECATEDMmolLThree and RateDEPRECATEDMmolLTwo } case calculator.Type: diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index d63696c519..09463cbb20 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -49,18 +49,66 @@ var _ = Describe("back-37", func() { Expect(revertSet).Should(HaveKeyWithValue("percent", float64(0.47857142857142865))) }) + It("cgm settings with blood glucose precsion updates", func() { + applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.CGMSetting)) + + Expect(applySet).Should(HaveLen(4)) + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "gyyB8OqbErdW2aOOo8POTXk1SNJmu5gDEIaCugTVn3M="})) + Expect(applySet).Should(HaveKeyWithValue("lowAlerts.level", 3.88552)) + Expect(applySet).Should(HaveKeyWithValue("highAlerts.level", 22.20299)) + Expect(applySet).Should(HaveKeyWithValue("rateOfChangeAlert", map[string]interface{}{ + "fallRate": map[string]interface{}{ + "rate": -0.16652243973136602, + "enabled": false, + }, + "riseRate": map[string]interface{}{ + "rate": 0.16652243973136602, + "enabled": false, + }, + })) + + Expect(applyUnset).Should(HaveLen(2)) + Expect(applyUnset).Should(HaveKey("rateOfChangeAlerts")) + Expect(applyUnset).Should(HaveKey("localTime")) + + Expect(revertSet).Should(HaveLen(4)) + Expect(revertSet).Should(HaveKeyWithValue("lowAlerts.level", 3.8855235937318735)) + Expect(revertSet).Should(HaveKeyWithValue("highAlerts.level", 22.202991964182132)) + Expect(revertSet).Should(HaveKeyWithValue("rateOfChangeAlerts", map[string]interface{}{ + "fallRate": map[string]interface{}{ + "rate": -0.16652243973136602, + "enabled": false, + }, + "riseRate": map[string]interface{}{ + "rate": 0.16652243973136602, + "enabled": false, + }, + })) + + Expect(revertUnset).Should(HaveLen(2)) + Expect(revertUnset).Should(HaveKey("_deduplicator")) + Expect(revertUnset).Should(HaveKey("rateOfChangeAlert")) + }) + It("pump settings with blood glucose precsion updates", func() { applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.PumpSettingsTandem)) + Expect(applySet).Should(HaveLen(6)) Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "l5e6HoVqMu3ZOUjqaky/m6ZNw+D0UFxbYw/fM9P4PXc="})) Expect(applySet).Should(HaveKeyWithValue("bgTargets.Simple.0.target", 5.55075)) Expect(applySet).Should(HaveKeyWithValue("bgTargets.Simple.1.target", 5.55075)) Expect(applySet).Should(HaveKeyWithValue("bgTargets.Standard.0.target", 5.55075)) Expect(applySet).Should(HaveKeyWithValue("bgTargets.Standard.1.target", 5.55075)) Expect(applySet).Should(HaveKeyWithValue("units.bg", "mmol/L")) + + Expect(applyUnset).Should(HaveLen(1)) Expect(applyUnset).Should(HaveKeyWithValue("localTime", "")) + + Expect(revertUnset).Should(HaveLen(1)) Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + + Expect(revertSet).Should(HaveLen(6)) Expect(revertSet).Should(HaveKeyWithValue("localTime", "2017-11-05T12:56:51.000Z")) Expect(revertSet).Should(HaveKeyWithValue("bgTargets.Simple.0.target", 5.550747991045533)) Expect(revertSet).Should(HaveKeyWithValue("bgTargets.Simple.1.target", 5.550747991045533)) From 31d4d6b90e1d8eee25ba2cbe9351cebaad57f400 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 16 Apr 2024 17:20:28 +1200 Subject: [PATCH 296/413] move comment --- migrations/20231128_jellyfish_migration/utils/utils.go | 2 -- migrations/20231128_jellyfish_migration/utils/utils_test.go | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go index 08ee95151a..eb77e51d14 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ b/migrations/20231128_jellyfish_migration/utils/utils.go @@ -185,8 +185,6 @@ func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[s updatedObject["highAlerts"] = highAlerts } } - // NOTE `rateOfChangeAlerts` not included as the fallRate.rate and riseRate.rate maintain orginal - // precicsion see platform/data/types/settings/cgm/rate_alert_DEPRECATED.go RateDEPRECATEDMmolLThree and RateDEPRECATEDMmolLTwo } case calculator.Type: diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 09463cbb20..46882e7143 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -56,6 +56,8 @@ var _ = Describe("back-37", func() { Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "gyyB8OqbErdW2aOOo8POTXk1SNJmu5gDEIaCugTVn3M="})) Expect(applySet).Should(HaveKeyWithValue("lowAlerts.level", 3.88552)) Expect(applySet).Should(HaveKeyWithValue("highAlerts.level", 22.20299)) + // NOTE `rateOfChangeAlert` does not truncate the fallRate.rate and riseRate.rate + // see platform/data/types/settings/cgm/rate_alert_DEPRECATED.go RateDEPRECATEDMmolLThree and RateDEPRECATEDMmolLTwo Expect(applySet).Should(HaveKeyWithValue("rateOfChangeAlert", map[string]interface{}{ "fallRate": map[string]interface{}{ "rate": -0.16652243973136602, From ee8050b9cbdaf38fff44c9b1a1d4260b6a93ba96 Mon Sep 17 00:00:00 2001 From: Jamie Bate Date: Thu, 25 Apr 2024 12:32:52 +1200 Subject: [PATCH 297/413] Jf migration history (#712) * baseline with test for each update applied during migration --- .../utils/data_migration_test.go | 7 +- .../utils/test/data.go | 95 ++- .../utils/utils_test.go | 562 ++++++++++++------ 3 files changed, 454 insertions(+), 210 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration_test.go b/migrations/20231128_jellyfish_migration/utils/data_migration_test.go index 70f6ebeb28..05973327cb 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration_test.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration_test.go @@ -111,7 +111,9 @@ var _ = Describe("back-37", func() { stats := migration.GetStats() Expect(stats.Errored).To(Equal(0)) Expect(stats.Fetched).To(Equal(datumCount)) - Expect(stats.Applied).To(Equal(datumCount * 3)) + // There are 'at least' 2000 changes applied but we don't know the exact amount + // as it varies depending which types are included in the original data + Expect(stats.Applied > datumCount*2).To(BeTrue()) cur, err := collection.Find(ctx, bson.D{}) Expect(err).To(BeNil()) @@ -122,14 +124,13 @@ var _ = Describe("back-37", func() { for _, item := range migrated { Expect(item).Should(HaveKey("_deduplicator")) + Expect(item["_deduplicator"]).Should(HaveKey("hash")) Expect(item).Should(HaveKey(migration.GetSettings().RollbackSectionName)) - Expect(item).ShouldNot(HaveKey("localTime")) } }) It("apply then rollback migration will return the data to its orginal state", func() { - collection := store.GetCollection("testRollback") Expect(setCollectionData(ctx, collection, testData)).To(Succeed()) diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go index d78e2b2b79..3a548ecfec 100644 --- a/migrations/20231128_jellyfish_migration/utils/test/data.go +++ b/migrations/20231128_jellyfish_migration/utils/test/data.go @@ -18,7 +18,6 @@ func base(deviceID string) map[string]interface{} { "deviceId": deviceID, "deviceTime": "2017-11-05T12:56:51", "id": "3f0075ad57ad603c83dc1e1a76aefcaf", - "localTime": "2017-11-05T12:56:51.000Z", "_userId": "8da6e693b8", "_groupId": "87df73fd41", "createdTime": "2022-06-21T22:40:07.732+00:00", @@ -36,7 +35,6 @@ func baseWithTime(deviceID string, groupID string, userID string, t time.Time) m "deviceId": deviceID, "deviceTime": t.Format("2006-01-02T15:04:05"), "id": "3f0075ad57ad603c83dc1e1a76aefcaf", - "localTime": t.Format("2006-01-02T15:04:05.999Z"), "_userId": userID, "_groupId": groupID, "createdTime": now.Format("2006-01-02T15:04:05.999+07:00"), @@ -67,7 +65,7 @@ func dexG5MobDatumStringAnnotations(datum map[string]interface{}) map[string]int func tandemPumpSettingsDatum(datum map[string]interface{}) map[string]interface{} { datum["type"] = "pumpSettings" datum["activeSchedule"] = "Simple" - datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mg/dL"} + datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mmol/l"} datum["basalSchedules"] = map[string]interface{}{ "Simple": []map[string]interface{}{ {"rate": 0.5, "start": 0}, @@ -99,17 +97,6 @@ func tandemPumpSettingsDatum(datum map[string]interface{}) map[string]interface{ }, } - datum["bgTargets"] = map[string]interface{}{ - "Simple": []map[string]interface{}{ - {"target": 5.550747991045533, "start": 0}, - {"target": 5.550747991045533, "start": 46800000}, - }, - "Standard": []map[string]interface{}{ - {"target": 5.550747991045533, "start": 0}, - {"target": 5.550747991045533, "start": 46800000}, - }, - } - datum["payload"] = map[string]interface{}{ "logIndices": []interface{}{0}, } @@ -120,7 +107,7 @@ func tandemPumpSettingsDatum(datum map[string]interface{}) map[string]interface{ func tandemPumpSettingsWithSleepScheduleDatum(datum map[string]interface{}) map[string]interface{} { datum["type"] = "pumpSettings" datum["activeSchedule"] = "Simple" - datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mg/dL"} + datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mmol/L"} datum["basalSchedules"] = map[string]interface{}{ "Simple": []map[string]interface{}{ {"rate": 0.5, "start": 0}, @@ -167,8 +154,6 @@ func tandemPumpSettingsWithSleepScheduleDatum(datum map[string]interface{}) map[ "logIndices": []interface{}{0}, } - //## TODO test for [pumpSettings] sleepSchedules []interface {}{map[string]interface {}{"days":[]interface {}{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}, "enabled":true, "end":25200, "start":82800}, map[string]interface {}{"days":[]interface {}{"Sunday"}, "enabled":false, "end":32400, "start":3600}} - datum["sleepSchedules"] = []interface{}{ map[string]interface{}{"days": []interface{}{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}, "enabled": true, "end": 25200, "start": 82800}, map[string]interface{}{"days": []interface{}{"Sunday"}, "enabled": false, "end": 32400, "start": 3600}, @@ -180,7 +165,7 @@ func tandemPumpSettingsWithSleepScheduleDatum(datum map[string]interface{}) map[ func carelinkPumpSettings(datum map[string]interface{}) map[string]interface{} { datum["type"] = "pumpSettings" datum["activeSchedule"] = "standard" - datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mg/dL"} + datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mmol/L"} datum["basalSchedules"] = map[string]interface{}{ "standard": []map[string]interface{}{ {"rate": 0.5, "start": 0}, @@ -243,6 +228,41 @@ func omnipodPumpSettingsDatum(datum map[string]interface{}) map[string]interface return datum } +func pumpSettingsWithTargetsDatum(datum map[string]interface{}) map[string]interface{} { + datum["type"] = "pumpSettings" + datum["activeSchedule"] = "test" + datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mmol/L"} + datum["basalSchedules"] = map[string]interface{}{ + "test": []map[string]interface{}{ + {"rate": 0.5, "start": 0}, + {"rate": 1.35, "start": 55800000}, + }, + "weekend b": []map[string]interface{}{}, + } + datum["carbRatio"] = []map[string]interface{}{ + {"amount": 10, "start": 0}, + {"amount": 10, "start": 32400000}, + } + datum["insulinSensitivity"] = []map[string]interface{}{ + {"amount": 2.7753739955227665, "start": 0}, + {"amount": 2.7753739955227665, "start": 46800000}, + } + + datum["bgTarget"] = []map[string]interface{}{ + {"target": 5.550747991045533, "start": 0, "high": 7.2159723883591935}, + } + + datum["bgTargetPhysicalActivity"] = map[string]interface{}{ + "low": 2.7753739955227665, "high": 7.2159723883591935, + } + + datum["bgTargetPreprandial"] = map[string]interface{}{ + "low": 2.7753739955227665, "high": 7.2159723883591935, + } + + return datum +} + func omnipodPumpSettingsDatumTargetSet(datum map[string]interface{}) map[string]interface{} { datum["type"] = "pumpSettings" datum["activeSchedule"] = "Mine-2016" @@ -380,6 +400,17 @@ func emptyPayload(datum map[string]interface{}) map[string]interface{} { return datum } +func extraFields(datum map[string]interface{}) map[string]interface{} { + datum["payload"] = map[string]interface{}{} + datum["type"] = "cbg" + datum["units"] = "mmol/L" + datum["value"] = 8.1596 + datum["index"] = 0 + datum["localTime"] = "2017-11-05T12:56:51.000Z" + datum["jsDate"] = "2017-11-05T12:56:51.000Z" + return datum +} + func pumpSettingsWithBolus(datum map[string]interface{}) map[string]interface{} { datum = tandemPumpSettingsDatum(datum) datum["bolus"] = &pump.BolusMap{ @@ -389,6 +420,28 @@ func pumpSettingsWithBolus(datum map[string]interface{}) map[string]interface{} return datum } +// payload as a string rather than object or array +func cbgDatum(datum map[string]interface{}) map[string]interface{} { + datum["type"] = "cbg" + datum["units"] = "mmol/L" + datum["value"] = 3.8855235937318735 + return datum +} + +func smbgDatum(datum map[string]interface{}) map[string]interface{} { + datum["type"] = "smbg" + datum["units"] = "mmol/L" + datum["value"] = 22.202991964182132 + return datum +} + +func bloodKetoneDatum(datum map[string]interface{}) map[string]interface{} { + datum["type"] = "bloodKetone" + datum["units"] = "mmol/L" + datum["value"] = 7.2159723883591935 + return datum +} + var CBGDexcomG5StringPayloadDatum = dexG5MobDatumStringPayload(base("DexG5Mob_iPhone")) var CBGDexcomG5StringAnnotationsDatum = dexG5MobDatumStringAnnotations(base("DexG5Mob_iPhone")) var PumpSettingsTandem = tandemPumpSettingsDatum(base("tandem99999999")) @@ -402,7 +455,13 @@ var ReservoirChangeWithStatus = reservoirChangeDeviceEventDatum(base("InsOmn-111 var AlarmDeviceEventDatum = alarmDeviceEventDatum(base("tandemCIQ100000000000")) var CGMSetting = cgmSettingsDatum(base("DexG5MobRec-1111111111111")) var EmptyPayloadDatum = emptyPayload(base("Dex-device")) +var ExtraFieldsDatum = extraFields(base("my-device")) var PumpSettingsWithBolusDatum = pumpSettingsWithBolus(base("tandem99999999")) +var PumpSettingsWithTarget = pumpSettingsWithTargetsDatum(base("my-pump-123")) + +var SMBGValueDatum = smbgDatum(base("smbg-device-123")) +var CBGValueDatum = cbgDatum(base("cbg-device-987")) +var BloodKetoneValueDatum = bloodKetoneDatum(base("blood-ketone-device-456")) func BulkJellyfishData(deviceID string, groupID string, userID string, requiredRecords int) []map[string]interface{} { data := []map[string]interface{}{} diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go index 46882e7143..542af171f9 100644 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ b/migrations/20231128_jellyfish_migration/utils/utils_test.go @@ -29,242 +29,426 @@ var _ = Describe("back-37", func() { Expect(apply).ToNot(BeNil()) Expect(revert).ToNot(BeNil()) - applySet = apply[0]["$set"] - applyUnset = apply[1]["$unset"] - revertUnset = revert[0]["$unset"] - revertSet = revert[1]["$set"] - + if apply[0] != nil && apply[0]["$set"] != nil { + applySet = apply[0]["$set"] + } + if len(apply) == 2 { + if apply[1]["$unset"] != nil { + applyUnset = apply[1]["$unset"] + } + } + if revert[0] != nil && revert[0]["$unset"] != nil { + revertUnset = revert[0]["$unset"] + } + if len(revert) == 2 { + if revert[1]["$set"] != nil { + revertSet = revert[1]["$set"] + } + } return applySet, applyUnset, revertUnset, revertSet } var _ = Describe("ProcessDatum", func() { - It("basal with unwanted percent feild", func() { + It("smbg only sets or reverts _deduplicator and value", func() { - applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.AutomatedBasalTandem)) + applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.SMBGValueDatum)) - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "YOItOWBgIIoEkqVsBq9yrOZ5utmsKTIezszpGBj5Vpc="})) - Expect(applyUnset).Should(HaveKeyWithValue("percent", "")) + Expect(applySet).Should(HaveLen(2)) + Expect(revertUnset).Should(HaveLen(1)) + Expect(applyUnset).Should(BeNil()) + Expect(revertSet).Should(HaveLen(1)) + + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "Q3DdX+M2N0kmtylZBiObYDt7JoFzWNkLWJaYcXXd9Zw="})) + Expect(applySet).Should(HaveKeyWithValue("value", 22.20299)) Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - Expect(revertSet).Should(HaveKeyWithValue("percent", float64(0.47857142857142865))) - }) + Expect(revertSet).Should(HaveKeyWithValue("value", 22.202991964182132)) - It("cgm settings with blood glucose precsion updates", func() { - applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.CGMSetting)) - - Expect(applySet).Should(HaveLen(4)) - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "gyyB8OqbErdW2aOOo8POTXk1SNJmu5gDEIaCugTVn3M="})) - Expect(applySet).Should(HaveKeyWithValue("lowAlerts.level", 3.88552)) - Expect(applySet).Should(HaveKeyWithValue("highAlerts.level", 22.20299)) - // NOTE `rateOfChangeAlert` does not truncate the fallRate.rate and riseRate.rate - // see platform/data/types/settings/cgm/rate_alert_DEPRECATED.go RateDEPRECATEDMmolLThree and RateDEPRECATEDMmolLTwo - Expect(applySet).Should(HaveKeyWithValue("rateOfChangeAlert", map[string]interface{}{ - "fallRate": map[string]interface{}{ - "rate": -0.16652243973136602, - "enabled": false, - }, - "riseRate": map[string]interface{}{ - "rate": 0.16652243973136602, - "enabled": false, - }, - })) - - Expect(applyUnset).Should(HaveLen(2)) - Expect(applyUnset).Should(HaveKey("rateOfChangeAlerts")) - Expect(applyUnset).Should(HaveKey("localTime")) - - Expect(revertSet).Should(HaveLen(4)) - Expect(revertSet).Should(HaveKeyWithValue("lowAlerts.level", 3.8855235937318735)) - Expect(revertSet).Should(HaveKeyWithValue("highAlerts.level", 22.202991964182132)) - Expect(revertSet).Should(HaveKeyWithValue("rateOfChangeAlerts", map[string]interface{}{ - "fallRate": map[string]interface{}{ - "rate": -0.16652243973136602, - "enabled": false, - }, - "riseRate": map[string]interface{}{ - "rate": 0.16652243973136602, - "enabled": false, - }, - })) - - Expect(revertUnset).Should(HaveLen(2)) - Expect(revertUnset).Should(HaveKey("_deduplicator")) - Expect(revertUnset).Should(HaveKey("rateOfChangeAlert")) }) - It("pump settings with blood glucose precsion updates", func() { - - applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.PumpSettingsTandem)) + It("cbg only sets or reverts _deduplicator and value", func() { - Expect(applySet).Should(HaveLen(6)) - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "l5e6HoVqMu3ZOUjqaky/m6ZNw+D0UFxbYw/fM9P4PXc="})) - Expect(applySet).Should(HaveKeyWithValue("bgTargets.Simple.0.target", 5.55075)) - Expect(applySet).Should(HaveKeyWithValue("bgTargets.Simple.1.target", 5.55075)) - Expect(applySet).Should(HaveKeyWithValue("bgTargets.Standard.0.target", 5.55075)) - Expect(applySet).Should(HaveKeyWithValue("bgTargets.Standard.1.target", 5.55075)) - Expect(applySet).Should(HaveKeyWithValue("units.bg", "mmol/L")) - - Expect(applyUnset).Should(HaveLen(1)) - Expect(applyUnset).Should(HaveKeyWithValue("localTime", "")) + applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.CBGValueDatum)) + Expect(applySet).Should(HaveLen(2)) Expect(revertUnset).Should(HaveLen(1)) + Expect(applyUnset).Should(BeNil()) + Expect(revertSet).Should(HaveLen(1)) + + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "kDdzWxsC4qNdfnnuWDYDX+fkZtFF7ZI/ZvvBL5PDa+s="})) + Expect(applySet).Should(HaveKeyWithValue("value", 3.88552)) Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + Expect(revertSet).Should(HaveKeyWithValue("value", 3.8855235937318735)) - Expect(revertSet).Should(HaveLen(6)) - Expect(revertSet).Should(HaveKeyWithValue("localTime", "2017-11-05T12:56:51.000Z")) - Expect(revertSet).Should(HaveKeyWithValue("bgTargets.Simple.0.target", 5.550747991045533)) - Expect(revertSet).Should(HaveKeyWithValue("bgTargets.Simple.1.target", 5.550747991045533)) - Expect(revertSet).Should(HaveKeyWithValue("bgTargets.Standard.0.target", 5.550747991045533)) - Expect(revertSet).Should(HaveKeyWithValue("bgTargets.Standard.1.target", 5.550747991045533)) - Expect(revertSet).Should(HaveKeyWithValue("units.bg", "mg/dL")) }) - It("pump settings with sleep schedule updates", func() { + It("bloodKetone only sets or reverts _deduplicator and value", func() { - applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.PumpSettingsWithSleepScheduleTandem)) + applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.BloodKetoneValueDatum)) - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "l5e6HoVqMu3ZOUjqaky/m6ZNw+D0UFxbYw/fM9P4PXc="})) - Expect(applySet).Should(HaveKey("sleepSchedules")) + Expect(applySet).Should(HaveLen(2)) + Expect(applyUnset).Should(BeNil()) + Expect(revertUnset).Should(HaveLen(1)) + Expect(revertSet).Should(HaveLen(1)) - applyObj := applySet.(primitive.M) + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "nkLnx6jBepJGYnBs3xOKCT8wFP5jYTqzi5Dq2NXXy+A="})) + Expect(applySet).Should(HaveKeyWithValue("value", 7.21597)) + Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + Expect(revertSet).Should(HaveKeyWithValue("value", 7.2159723883591935)) - actualSchedules := applyObj["sleepSchedules"] + }) - expectedSchedules := map[string]interface{}{ - "1": map[string]interface{}{ - "enabled": true, - "days": []interface{}{"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"}, - "start": 82800, - "end": 25200, - }, - "2": map[string]interface{}{ - "enabled": false, - "days": []interface{}{"sunday"}, - "start": 3600, - "end": 32400, - }, - } + It("basal only sets or reverts _deduplicator", func() { + + applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.AutomatedBasalTandem)) - Expect(fmt.Sprintf("%v", actualSchedules)).To(Equal(fmt.Sprintf("%v", expectedSchedules))) + Expect(applySet).Should(HaveLen(1)) + Expect(applyUnset).Should(HaveLen(1)) + Expect(revertUnset).Should(HaveLen(1)) + Expect(revertSet).Should(HaveLen(1)) - Expect(applyUnset).Should(HaveKeyWithValue("localTime", "")) + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "YOItOWBgIIoEkqVsBq9yrOZ5utmsKTIezszpGBj5Vpc="})) + Expect(applyUnset).Should(HaveKeyWithValue("percent", "")) Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - Expect(revertSet).Should(HaveKey("sleepSchedules")) - revertSetObj := revertSet.(primitive.M) - actualRevrtSchedules := revertSetObj["sleepSchedules"] - - originalSchedules := []map[string]interface{}{ - { - "enabled": true, - "days": []interface{}{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}, - "start": 82800, - "end": 25200, - }, - { - "enabled": false, - "days": []interface{}{"Sunday"}, - "start": 3600, - "end": 32400, - }, - } + Expect(revertSet).Should(HaveKeyWithValue("percent", 0.47857142857142865)) - Expect(fmt.Sprintf("%v", actualRevrtSchedules)).To(Equal(fmt.Sprintf("%v", originalSchedules))) + }) + Describe("cgmSettings datum", func() { + It("will make _deduplicator, lowAlerts and highAlerts and rateOfChangeAlert updates", func() { + applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.CGMSetting)) + + Expect(applySet).Should(HaveLen(4)) + Expect(applyUnset).Should(HaveLen(1)) + Expect(revertUnset).Should(HaveLen(2)) + Expect(revertSet).Should(HaveLen(3)) + + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "gyyB8OqbErdW2aOOo8POTXk1SNJmu5gDEIaCugTVn3M="})) + Expect(applySet).Should(HaveKeyWithValue("lowAlerts.level", 3.88552)) + Expect(applySet).Should(HaveKeyWithValue("highAlerts.level", 22.20299)) + Expect(applySet).Should(HaveKeyWithValue( + "rateOfChangeAlert", map[string]interface{}{ + "fallRate": map[string]interface{}{ + "enabled": false, + "rate": float64(-0.16652243973136602), + }, + "riseRate": map[string]interface{}{ + "enabled": false, + "rate": float64(0.16652243973136602), + }, + }, + )) + Expect(applyUnset).Should(HaveKeyWithValue("rateOfChangeAlerts", "")) + Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + Expect(revertUnset).Should(HaveKeyWithValue("rateOfChangeAlert", "")) + Expect(revertSet).Should(HaveKeyWithValue("lowAlerts.level", 3.8855235937318735)) + Expect(revertSet).Should(HaveKeyWithValue("highAlerts.level", 22.202991964182132)) + Expect(revertSet).Should(HaveKeyWithValue("rateOfChangeAlerts", map[string]interface{}{ + "fallRate": map[string]interface{}{ + "enabled": false, + "rate": float64(-0.16652243973136602), + }, + "riseRate": map[string]interface{}{ + "enabled": false, + "rate": float64(0.16652243973136602), + }, + })) + }) + }) + Describe("pumpSettings datum", func() { + + It("will make _deduplicator, and bg precision updates ", func() { + applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.PumpSettingsTandem)) + + Expect(applySet).Should(HaveLen(2)) + Expect(revertUnset).Should(HaveLen(1)) + Expect(applyUnset).Should(BeNil()) + Expect(revertSet).Should(HaveLen(1)) + + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "l5e6HoVqMu3ZOUjqaky/m6ZNw+D0UFxbYw/fM9P4PXc="})) + Expect(applySet).Should(HaveKeyWithValue("units.bg", "mmol/L")) + Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + Expect(revertSet).Should(HaveKeyWithValue("units.bg", "mmol/l")) + }) + + It("will make _deduplicator and sleepSchedules updates", func() { + + applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.PumpSettingsWithSleepScheduleTandem)) + + Expect(applySet).Should(HaveLen(6)) + Expect(applyUnset).Should(BeNil()) + Expect(revertUnset).Should(HaveLen(1)) + Expect(revertSet).Should(HaveLen(5)) + + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "l5e6HoVqMu3ZOUjqaky/m6ZNw+D0UFxbYw/fM9P4PXc="})) + + Expect(applySet).Should(HaveKeyWithValue("bgTargets.Simple.0.target", 5.55075)) + Expect(applySet).Should(HaveKeyWithValue("bgTargets.Simple.1.target", 5.55075)) + Expect(applySet).Should(HaveKeyWithValue("bgTargets.Standard.0.target", 5.55075)) + Expect(applySet).Should(HaveKeyWithValue("bgTargets.Standard.1.target", 5.55075)) + + Expect(applySet).Should(HaveKey("sleepSchedules")) + + applyObj := applySet.(primitive.M) + + actualUpdatedSleepSchedules := applyObj["sleepSchedules"] + + expectedUpdatedSleepSchedules := map[string]interface{}{ + "1": map[string]interface{}{ + "enabled": true, + "days": []interface{}{"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"}, + "start": 82800, + "end": 25200, + }, + "2": map[string]interface{}{ + "enabled": false, + "days": []interface{}{"sunday"}, + "start": 3600, + "end": 32400, + }, + } + + Expect(fmt.Sprintf("%v", actualUpdatedSleepSchedules)).To(Equal(fmt.Sprintf("%v", expectedUpdatedSleepSchedules))) + + Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + Expect(revertSet).Should(HaveKeyWithValue("bgTargets.Simple.0.target", 5.550747991045533)) + Expect(revertSet).Should(HaveKeyWithValue("bgTargets.Simple.1.target", 5.550747991045533)) + Expect(revertSet).Should(HaveKeyWithValue("bgTargets.Standard.0.target", 5.550747991045533)) + Expect(revertSet).Should(HaveKeyWithValue("bgTargets.Standard.1.target", 5.550747991045533)) + Expect(revertSet).Should(HaveKey("sleepSchedules")) + revertSetObj := revertSet.(primitive.M) + actualRevertSetSleepSchedules := revertSetObj["sleepSchedules"] + + expectedRevertSleepSchedules := []map[string]interface{}{ + { + "enabled": true, + "days": []interface{}{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}, + "start": 82800, + "end": 25200, + }, + { + "enabled": false, + "days": []interface{}{"Sunday"}, + "start": 3600, + "end": 32400, + }, + } + + Expect(fmt.Sprintf("%v", actualRevertSetSleepSchedules)).To(Equal(fmt.Sprintf("%v", expectedRevertSleepSchedules))) + + }) + + It("with make bgTraget updates and set _deduplicator", func() { + applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.PumpSettingsCarelink)) + + Expect(applySet).Should(HaveLen(3)) + Expect(revertUnset).Should(HaveLen(1)) + Expect(applyUnset).Should(BeNil()) + Expect(revertSet).Should(HaveLen(2)) + + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "LgRaGs4QkIBV9sHUjurpMt/ALU+7F7ZlU8xNxhkTQwQ="})) + Expect(applySet).Should(HaveKeyWithValue("bgTarget.0.target", 5.55075)) + Expect(applySet).Should(HaveKeyWithValue("bgTarget.1.target", 5.55075)) + + Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + Expect(revertSet).Should(HaveKeyWithValue("bgTarget.0.target", 5.550747991045533)) + Expect(revertSet).Should(HaveKeyWithValue("bgTarget.1.target", 5.550747991045533)) + }) + + It("with make bgTraget, bgTargetPhysicalActivity, bgTargetPreprandial updates and set _deduplicator", func() { + applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.PumpSettingsWithTarget)) + + Expect(applySet).Should(HaveLen(7)) + Expect(applyUnset).Should(BeNil()) + Expect(revertSet).Should(HaveLen(6)) + Expect(revertUnset).Should(HaveLen(1)) + + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "91MQsmPpTjboyucNKq23VOvWUx0afj3GSexzKvg8xPA="})) + Expect(applySet).Should(HaveKeyWithValue("bgTarget.0.target", 5.55075)) + Expect(applySet).Should(HaveKeyWithValue("bgTarget.0.high", 7.21597)) + Expect(applySet).Should(HaveKeyWithValue("bgTargetPhysicalActivity.low", 2.77537)) + Expect(applySet).Should(HaveKeyWithValue("bgTargetPhysicalActivity.high", 7.21597)) + Expect(applySet).Should(HaveKeyWithValue("bgTargetPreprandial.low", 2.77537)) + Expect(applySet).Should(HaveKeyWithValue("bgTargetPreprandial.high", 7.21597)) + + Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + Expect(revertSet).Should(HaveKeyWithValue("bgTarget.0.target", 5.550747991045533)) + Expect(revertSet).Should(HaveKeyWithValue("bgTarget.0.high", 7.2159723883591935)) + Expect(revertSet).Should(HaveKeyWithValue("bgTargetPhysicalActivity.low", 2.7753739955227665)) + Expect(revertSet).Should(HaveKeyWithValue("bgTargetPhysicalActivity.high", 7.2159723883591935)) + Expect(revertSet).Should(HaveKeyWithValue("bgTargetPreprandial.low", 2.7753739955227665)) + Expect(revertSet).Should(HaveKeyWithValue("bgTargetPreprandial.high", 7.2159723883591935)) + }) + + It("will male boluses updates and set _deduplicator", func() { + bsonObj := getBSONData(test.PumpSettingsWithBolusDatum) + applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) + + Expect(applySet).Should(HaveLen(3)) + Expect(revertUnset).Should(HaveLen(2)) + + Expect(applyUnset).Should(HaveLen(1)) + Expect(revertSet).Should(HaveLen(2)) + + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "l5e6HoVqMu3ZOUjqaky/m6ZNw+D0UFxbYw/fM9P4PXc="})) + Expect(applySet).Should(HaveKeyWithValue("units.bg", "mmol/L")) + revertSetObj := revertSet.(primitive.M) + Expect(applySet).Should(HaveKeyWithValue("boluses", revertSetObj["bolus"])) + Expect(applyUnset).Should(HaveKeyWithValue("bolus", "")) + + Expect(revertSet).Should(HaveKey("bolus")) + Expect(revertSet).Should(HaveKeyWithValue("units.bg", "mmol/l")) + Expect(revertUnset).Should(HaveKeyWithValue("boluses", "")) + Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + }) }) - It("wizard with bgInput and bgTarget glucose updates", func() { + Describe("wizard datum", func() { + It("only sets _deduplicator and bgInput, bgTarget and ignores the bolus and bolusId link", func() { - applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.WizardTandem)) + bsonObj := getBSONData(test.WizardTandem) + Expect(bsonObj).Should(HaveKeyWithValue("bolus", "g2h6nohp5sdndpvl2l8kdete00lle4gt")) - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "orP5cbifS8h0f3HWZcTOIf4B431HO1OReg9o1nmFnU4="})) - Expect(applySet).Should(HaveKeyWithValue("bgInput", 4.4406)) - Expect(applySet).Should(HaveKeyWithValue("bgTarget.target", 4.4406)) - Expect(applyUnset).Should(HaveKeyWithValue("localTime", "")) - Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - Expect(revertSet).Should(HaveKeyWithValue("localTime", "2017-11-05T12:56:51.000Z")) - Expect(revertSet).Should(HaveKeyWithValue("bgInput", 4.440598392836427)) - Expect(revertSet).Should(HaveKeyWithValue("bgTarget.target", 4.440598392836427)) - }) + applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) - It("pump settings with bgTraget glucose updates", func() { + Expect(applySet).Should(HaveLen(3)) + Expect(applyUnset).Should(HaveLen(5)) - applySet, _, revertUnset, revertSet := setup(getBSONData(test.PumpSettingsCarelink)) + Expect(revertUnset).Should(HaveLen(1)) + Expect(revertSet).Should(HaveLen(7)) - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "LgRaGs4QkIBV9sHUjurpMt/ALU+7F7ZlU8xNxhkTQwQ="})) - Expect(applySet).Should(HaveKeyWithValue("bgTarget.0.target", 5.55075)) - Expect(applySet).Should(HaveKeyWithValue("bgTarget.1.target", 5.55075)) - Expect(applySet).Should(HaveKeyWithValue("units.bg", "mmol/L")) - Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - Expect(revertSet).Should(HaveKeyWithValue("bgTarget.0.target", 5.550747991045533)) - Expect(revertSet).Should(HaveKeyWithValue("bgTarget.1.target", 5.550747991045533)) - Expect(revertSet).Should(HaveKeyWithValue("units.bg", "mg/dL")) - }) + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "orP5cbifS8h0f3HWZcTOIf4B431HO1OReg9o1nmFnU4="})) + Expect(applySet).Should(HaveKeyWithValue("bgInput", 4.4406)) + Expect(applySet).Should(HaveKeyWithValue("bgTarget.target", 4.4406)) + Expect(applyUnset).Should(HaveKeyWithValue("rate", "")) + Expect(applyUnset).Should(HaveKeyWithValue("percent", "")) + Expect(applyUnset).Should(HaveKeyWithValue("duration", "")) + Expect(applyUnset).Should(HaveKeyWithValue("recommended.deliveryType", "")) + Expect(applyUnset).Should(HaveKeyWithValue("recommended.rate", "")) - It("will remove empty payload", func() { - _, applyUnset, _, revertSet := setup(getBSONData(test.EmptyPayloadDatum)) - Expect(applyUnset).Should(HaveKeyWithValue("payload", "")) - Expect(revertSet).Should(HaveKeyWithValue("payload", map[string]interface{}{})) - }) + Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + Expect(revertSet).Should(HaveKeyWithValue("bgInput", 4.440598392836427)) + Expect(revertSet).Should(HaveKeyWithValue("bgTarget.target", 4.440598392836427)) - It("will move misnamed bolus to boluses for pump setting", func() { - bsonObj := getBSONData(test.PumpSettingsWithBolusDatum) - applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) - Expect(applyUnset).Should(HaveKeyWithValue("bolus", "")) - Expect(applySet).Should(HaveKey("boluses")) - Expect(revertSet).Should(HaveKey("bolus")) - Expect(revertUnset).Should(HaveKeyWithValue("boluses", "")) - }) + Expect(revertSet).Should(HaveKeyWithValue("recommended.deliveryType", "scheduled")) + Expect(revertSet).Should(HaveKeyWithValue("recommended.rate", 0.7)) + Expect(revertSet).Should(HaveKeyWithValue("rate", 0.335)) + Expect(revertSet).Should(HaveKeyWithValue("duration", float64(300000))) + Expect(revertSet).Should(HaveKeyWithValue("percent", 0.47857142857142865)) - It("wizard datum will not have bolus link removed", func() { - bsonObj := getBSONData(test.WizardTandem) - Expect(bsonObj).Should(HaveKeyWithValue("bolus", "g2h6nohp5sdndpvl2l8kdete00lle4gt")) - applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) - Expect(applyUnset).ShouldNot(HaveKeyWithValue("bolus", "")) - Expect(applySet).ShouldNot(HaveKey("bolusId")) - Expect(revertSet).ShouldNot(HaveKey("bolus")) - Expect(revertUnset).ShouldNot(HaveKey("bolusId")) + }) }) - It("device event datum will not have status link removed", func() { - bsonObj := getBSONData(test.ReservoirChangeWithStatus) - Expect(bsonObj).Should(HaveKeyWithValue("status", "cvv61jde62b6i28bgot57f18bor5au1n")) - applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) - Expect(applyUnset).ShouldNot(HaveKeyWithValue("status", "")) - Expect(applySet).ShouldNot(HaveKey("statusId")) - Expect(revertSet).ShouldNot(HaveKey("status")) - Expect(revertUnset).ShouldNot(HaveKey("statusId")) - }) + Describe("deviceEvent datum", func() { + It("sets _deduplicator and ignores the status and statusId link", func() { + bsonObj := getBSONData(test.ReservoirChangeWithStatus) + Expect(bsonObj).Should(HaveKeyWithValue("status", "cvv61jde62b6i28bgot57f18bor5au1n")) + applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) - It("status device event datum with suspended status as suspended will not update it", func() { - bsonObj := getBSONData(test.AlarmDeviceEventDatum) - Expect(bsonObj).Should(HaveKeyWithValue("status", "suspended")) - applySet, _, _, revertSet := setup(bsonObj) - Expect(applySet).ShouldNot(HaveKey("status")) - Expect(revertSet).ShouldNot(HaveKey("status")) - }) + Expect(applySet).Should(HaveLen(1)) + Expect(revertUnset).Should(HaveLen(1)) + Expect(applyUnset).Should(BeNil()) + Expect(revertSet).Should(BeNil()) - It("will convert payload that is stored as a string", func() { - bsonObj := getBSONData(test.CBGDexcomG5StringPayloadDatum) - applySet, _, _, revertSet := setup(bsonObj) - Expect(applySet).Should(HaveKeyWithValue("payload", map[string]interface{}{"systemTime": "2017-11-05T18:56:51Z", "transmitterId": "410X6M", "transmitterTicks": 5.796922e+06, "trend": "flat", "trendRate": 0.6, "trendRateUnits": "mg/dL/min"})) - Expect(revertSet).Should(HaveKeyWithValue("payload", "{\"systemTime\":\"2017-11-05T18:56:51Z\",\"transmitterId\":\"410X6M\",\"transmitterTicks\":5796922,\"trend\":\"flat\",\"trendRate\":0.6,\"trendRateUnits\":\"mg/dL/min\"}")) - }) + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "yahFM0LCaLowGnmbqHijnOpfwkR3Ot/YVK7K5n5yIHg="})) + Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + }) - It("will convert annotations that are stored as a string", func() { - bsonObj := getBSONData(test.CBGDexcomG5StringAnnotationsDatum) - applySet, _, _, revertSet := setup(bsonObj) + It("sets _deduplicator and ignores status suspended and will not update it", func() { + bsonObj := getBSONData(test.AlarmDeviceEventDatum) + Expect(bsonObj).Should(HaveKeyWithValue("status", "suspended")) - Expect(applySet).Should(HaveKey("annotations")) + applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) - expectedAnnotations := []interface{}{ - map[string]interface{}{"code": "bg/out-of-range", "threshold": 40, "value": "low"}, - } - applyObj := applySet.(primitive.M) - actualAnnotations := applyObj["annotations"] + Expect(applySet).Should(HaveLen(1)) + Expect(revertUnset).Should(HaveLen(1)) + Expect(applyUnset).Should(BeNil()) + Expect(revertSet).Should(BeNil()) + + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "co0AMaEqrFrInC2Ek+HqbvmZRr9WTT0rEnZ8JXpm2Hg="})) + Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + }) + }) - Expect(fmt.Sprintf("%v", actualAnnotations)).To(Equal(fmt.Sprintf("%v", expectedAnnotations))) + Describe("datum", func() { + It("payload will be migarted and _deduplicator set", func() { + bsonObj := getBSONData(test.CBGDexcomG5StringPayloadDatum) + applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) + + Expect(applySet).Should(HaveLen(2)) + Expect(revertUnset).Should(HaveLen(1)) + Expect(applyUnset).Should(BeNil()) + Expect(revertSet).Should(HaveLen(1)) + + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "Kix7EaZBCVwTaOR/LQPj6iJ08mFJOR/IR2nsvyDGtGA="})) + Expect(applySet).Should(HaveKeyWithValue("payload", map[string]interface{}{ + "transmitterId": "410X6M", + "transmitterTicks": 5.796922e+06, + "trend": "flat", + "trendRate": 0.6, + "trendRateUnits": "mg/dL/min", + "systemTime": "2017-11-05T18:56:51Z", + })) + Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + Expect(revertSet).Should(HaveKeyWithValue("payload", "{\"systemTime\":\"2017-11-05T18:56:51Z\",\"transmitterId\":\"410X6M\",\"transmitterTicks\":5796922,\"trend\":\"flat\",\"trendRate\":0.6,\"trendRateUnits\":\"mg/dL/min\"}")) + }) + It("payload will be migarted when empty and _deduplicator set", func() { + applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.EmptyPayloadDatum)) + Expect(applySet).Should(HaveLen(1)) + Expect(revertUnset).Should(HaveLen(1)) + Expect(applyUnset).Should(HaveLen(1)) + Expect(revertSet).Should(HaveLen(1)) + + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "dcXIRasQiatLHLG8oUjiG2yNSKetWpkC7GDMQ8ZpM/c="})) + Expect(applyUnset).Should(HaveKeyWithValue("payload", "")) + Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + Expect(revertSet).Should(HaveKeyWithValue("payload", map[string]interface{}{})) + }) + It("annotations will be migrated with _deduplicator", func() { + bsonObj := getBSONData(test.CBGDexcomG5StringAnnotationsDatum) + applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) + + Expect(applySet).Should(HaveLen(2)) + Expect(revertUnset).Should(HaveLen(1)) + Expect(applyUnset).Should(BeNil()) + Expect(revertSet).Should(HaveLen(1)) + + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "Kix7EaZBCVwTaOR/LQPj6iJ08mFJOR/IR2nsvyDGtGA="})) + Expect(applySet).Should(HaveKeyWithValue("annotations", []interface{}{map[string]interface{}{ + "code": "bg/out-of-range", + "threshold": float64(40), + "value": "low", + }})) + + Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + Expect(revertSet).Should(HaveKeyWithValue("annotations", "[{\"code\":\"bg/out-of-range\",\"threshold\":40,\"value\":\"low\"}]")) + + }) + + It("extra fields will be remobved and _deduplicator applied", func() { + bsonObj := getBSONData(test.ExtraFieldsDatum) + applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) + + Expect(applySet).Should(HaveLen(1)) + Expect(applyUnset).Should(HaveLen(4)) + Expect(revertSet).Should(HaveLen(4)) + Expect(revertUnset).Should(HaveLen(1)) + + Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "ZQYgkXIbB3hhhHAmCKivS46j2aHZMxhKzhA5w27PSFo="})) + Expect(applyUnset).Should(HaveKeyWithValue("index", "")) + Expect(applyUnset).Should(HaveKeyWithValue("jsDate", "")) + Expect(applyUnset).Should(HaveKeyWithValue("localTime", "")) + Expect(applyUnset).Should(HaveKeyWithValue("payload", "")) + + Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) + + Expect(revertSet).Should(HaveKeyWithValue("index", float64(0))) + Expect(revertSet).Should(HaveKeyWithValue("jsDate", "2017-11-05T12:56:51.000Z")) + Expect(revertSet).Should(HaveKeyWithValue("localTime", "2017-11-05T12:56:51.000Z")) + Expect(revertSet).Should(HaveKeyWithValue("payload", map[string]interface{}{})) + + }) - Expect(revertSet).Should(HaveKeyWithValue("annotations", "[{\"code\":\"bg/out-of-range\",\"threshold\":40,\"value\":\"low\"}]")) }) }) }) From b7d579ee31b343ef2584392d75d7d41def60caf8 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 29 May 2024 12:04:25 +1200 Subject: [PATCH 298/413] LegacyIdentityFields for hash --- data/datum.go | 1 + .../deduplicator/device_deactivate_hash.go | 70 +++++++++++++++++-- data/deduplicator/deduplicator/hash.go | 52 ++++++++++---- data/deduplicator/deduplicator/hash_test.go | 45 ++++++++++-- data/service/service/standard.go | 8 +++ data/test/datum.go | 17 +++++ data/types/activity/physical/physical.go | 26 +++++++ data/types/activity/physical/physical_test.go | 44 ++++++++++++ data/types/basal/basal.go | 29 ++++++++ data/types/basal/basal_test.go | 49 +++++++++++++ data/types/base.go | 8 +++ data/types/base_test.go | 16 +++++ data/types/blood/blood.go | 25 +++++++ data/types/blood/blood_test.go | 43 ++++++++++++ .../glucose/selfmonitored/selfmonitored.go | 16 +++++ .../selfmonitored/selfmonitored_test.go | 52 ++++++++++++++ data/types/bolus/bolus.go | 29 ++++++++ data/types/bolus/bolus_test.go | 50 +++++++++++++ data/types/device/device.go | 29 ++++++++ data/types/device/device_test.go | 50 +++++++++++++ data/types/food/food.go | 26 +++++++ data/types/food/food_test.go | 46 ++++++++++++ data/types/insulin/insulin.go | 26 +++++++ data/types/insulin/insulin_test.go | 44 ++++++++++++ data/types/settings/cgm/cgm.go | 25 +++++++ data/types/settings/cgm/cgm_test.go | 45 ++++++++++++ 26 files changed, 845 insertions(+), 26 deletions(-) diff --git a/data/datum.go b/data/datum.go index c06075ec34..34b880c0bd 100644 --- a/data/datum.go +++ b/data/datum.go @@ -16,6 +16,7 @@ type Datum interface { Normalize(normalizer Normalizer) IdentityFields() ([]string, error) + LegacyIdentityFields() ([]string, error) GetOrigin() *origin.Origin GetPayload() *metadata.Metadata diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index 019a1f3842..d22f7c6bd8 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -9,7 +9,16 @@ import ( "github.com/tidepool-org/platform/errors" ) +type HashType int + +const ( + _ HashType = iota + PlatformHash + LegacyHash +) + const DeviceDeactivateHashName = "org.tidepool.deduplicator.device.deactivate.hash" +const DeviceDeactivateLegacyHashName = "org.tidepool.deduplicator.device.deactivate.legacy.hash" var DeviceDeactivateHashDeviceManufacturerDeviceModels = map[string][]string{ "Abbott": {"FreeStyle Libre"}, @@ -18,10 +27,36 @@ var DeviceDeactivateHashDeviceManufacturerDeviceModels = map[string][]string{ "Trividia Health": {"TRUE METRIX", "TRUE METRIX AIR", "TRUE METRIX GO"}, } +var DeviceDeactivateLegacyHasheManufacturerDeviceModels = map[string][]string{ + "Tandem": {"T:Slim"}, + "InsuletOmniPod": {"Dash", "Eros"}, + //TODO: other devices here +} + type DeviceDeactivateHash struct { *Base } +func NewDeviceDeactivateLegacyHash() (*DeviceDeactivateHash, error) { + base, err := NewBase(DeviceDeactivateLegacyHashName, "0.0.0") + if err != nil { + return nil, err + } + + return &DeviceDeactivateHash{ + Base: base, + }, nil +} + +func (d *DeviceDeactivateHash) getHashType() (HashType, error) { + if d.name == DeviceDeactivateHashName { + return PlatformHash, nil + } else if d.name == DeviceDeactivateLegacyHashName { + return LegacyHash, nil + } + return 0, errors.New("unknown hash type") +} + func NewDeviceDeactivateHash() (*DeviceDeactivateHash, error) { base, err := NewBase(DeviceDeactivateHashName, "1.1.0") if err != nil { @@ -53,11 +88,28 @@ func (d *DeviceDeactivateHash) New(dataSet *dataTypesUpload.Upload) (bool, error return false, nil } - for _, deviceManufacturer := range *dataSet.DeviceManufacturers { - if allowedDeviceModels, found := DeviceDeactivateHashDeviceManufacturerDeviceModels[deviceManufacturer]; found { - for _, allowedDeviceModel := range allowedDeviceModels { - if allowedDeviceModel == *dataSet.DeviceModel { - return true, nil + hasher, err := d.getHashType() + + if err != nil { + return false, err + } + if hasher == PlatformHash { + for _, deviceManufacturer := range *dataSet.DeviceManufacturers { + if allowedDeviceModels, found := DeviceDeactivateHashDeviceManufacturerDeviceModels[deviceManufacturer]; found { + for _, allowedDeviceModel := range allowedDeviceModels { + if allowedDeviceModel == *dataSet.DeviceModel { + return true, nil + } + } + } + } + } else if hasher == LegacyHash { + for _, deviceManufacturer := range *dataSet.DeviceManufacturers { + if allowedDeviceModels, found := DeviceDeactivateLegacyHasheManufacturerDeviceModels[deviceManufacturer]; found { + for _, allowedDeviceModel := range allowedDeviceModels { + if allowedDeviceModel == *dataSet.DeviceModel { + return true, nil + } } } } @@ -88,7 +140,13 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore return errors.New("data set data is missing") } - if err := AssignDataSetDataIdentityHashes(dataSetData); err != nil { + hasher, err := d.getHashType() + + if err != nil { + return err + } + + if err := AssignDataSetDataIdentityHashes(dataSetData, hasher); err != nil { return err } diff --git a/data/deduplicator/deduplicator/hash.go b/data/deduplicator/deduplicator/hash.go index dc97d91508..57b47364f2 100644 --- a/data/deduplicator/deduplicator/hash.go +++ b/data/deduplicator/deduplicator/hash.go @@ -1,8 +1,11 @@ package deduplicator import ( + "crypto/sha1" "crypto/sha256" + "encoding/base32" "encoding/base64" + "fmt" "strings" "github.com/tidepool-org/platform/data" @@ -10,16 +13,27 @@ import ( "github.com/tidepool-org/platform/pointer" ) -func AssignDataSetDataIdentityHashes(dataSetData data.Data) error { +func AssignDataSetDataIdentityHashes(dataSetData data.Data, hasher HashType) error { for _, dataSetDatum := range dataSetData { - fields, err := dataSetDatum.IdentityFields() - if err != nil { - return errors.Wrap(err, "unable to gather identity fields for datum") - } - - hash, err := GenerateIdentityHash(fields) - if err != nil { - return errors.Wrap(err, "unable to generate identity hash for datum") + var hash string + if hasher == PlatformHash { + fields, err := dataSetDatum.IdentityFields() + if err != nil { + return errors.Wrap(err, "unable to gather identity fields for datum") + } + hash, err = GenerateIdentityHash(fields) + if err != nil { + return errors.Wrap(err, "unable to generate identity hash for datum") + } + } else if hasher == LegacyHash { + fields, err := dataSetDatum.IdentityFields() + if err != nil { + return errors.Wrap(err, "unable to gather legacy identity fields for datum") + } + hash, err = GenerateLegacyIdentityHash(fields) + if err != nil { + return errors.Wrap(err, "unable to generate identity hash for datum") + } } deduplicator := dataSetDatum.DeduplicatorDescriptor() @@ -44,12 +58,24 @@ func GenerateIdentityHash(identityFields []string) (string, error) { return "", errors.New("identity field is empty") } } - - identityString := strings.Join(identityFields, hashIdentityFieldsSeparator) + identityString := strings.Join(identityFields, "|") identitySum := sha256.Sum256([]byte(identityString)) identityHash := base64.StdEncoding.EncodeToString(identitySum[:]) - return identityHash, nil } -const hashIdentityFieldsSeparator = "|" +func GenerateLegacyIdentityHash(identityFields []string) (string, error) { + if len(identityFields) == 0 { + return "", errors.New("identity fields are missing") + } + hasher := sha1.New() + for _, identityField := range identityFields { + if identityField == "" { + return "", errors.New("identity field is empty") + } + hasher.Write([]byte(fmt.Sprintf("%v_", identityField))) + } + hasher.Write([]byte("bootstrap_")) + hash := hasher.Sum(nil) + return base32.NewEncoding("0123456789abcdefghijklmnopqrstuv").WithPadding('-').EncodeToString(hash), nil +} diff --git a/data/deduplicator/deduplicator/hash_test.go b/data/deduplicator/deduplicator/hash_test.go index 4674c17150..e65cfb9aa1 100644 --- a/data/deduplicator/deduplicator/hash_test.go +++ b/data/deduplicator/deduplicator/hash_test.go @@ -34,35 +34,35 @@ var _ = Describe("Hash", func() { }) It("returns successfully when the data is nil", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(nil)).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(nil, dataDeduplicatorDeduplicator.PlatformHash)).To(Succeed()) }) It("returns successfully when there is no data", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(data.Data{})).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(data.Data{}, dataDeduplicatorDeduplicator.PlatformHash)).To(Succeed()) }) It("returns an error when any datum returns an error getting identity fields", func() { dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: nil, Error: errors.New("test error")}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData)).To(MatchError("unable to gather identity fields for datum; test error")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.PlatformHash)).To(MatchError("unable to gather identity fields for datum; test error")) }) It("returns an error when any datum returns no identity fields", func() { dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: nil, Error: nil}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData)).To(MatchError("unable to generate identity hash for datum; identity fields are missing")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.PlatformHash)).To(MatchError("unable to generate identity hash for datum; identity fields are missing")) }) It("returns an error when any datum returns empty identity fields", func() { dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{}, Error: nil}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData)).To(MatchError("unable to generate identity hash for datum; identity fields are missing")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.PlatformHash)).To(MatchError("unable to generate identity hash for datum; identity fields are missing")) }) It("returns an error when any datum returns any empty identity fields", func() { dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), ""}, Error: nil}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData)).To(MatchError("unable to generate identity hash for datum; identity field is empty")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.PlatformHash)).To(MatchError("unable to generate identity hash for datum; identity field is empty")) }) Context("with identity fields", func() { @@ -79,7 +79,7 @@ var _ = Describe("Hash", func() { }) It("returns successfully", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData)).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.PlatformHash)).To(Succeed()) }) }) }) @@ -115,4 +115,35 @@ var _ = Describe("Hash", func() { Expect(dataDeduplicatorDeduplicator.GenerateIdentityHash([]string{"one", "two", "three", "four", "five"})).To(Equal("8HUIFZUXmOuySpngHvl+fJECoeELTiCRxwNxxgDzmVQ=")) }) }) + Context("GenerateLegacyIdentityHash", func() { + It("returns an error when identity fields is missing", func() { + hash, err := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash(nil) + Expect(err).To(MatchError("identity fields are missing")) + Expect(hash).To(BeEmpty()) + }) + + It("returns an error when identity fields is empty", func() { + hash, err := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash([]string{}) + Expect(err).To(MatchError("identity fields are missing")) + Expect(hash).To(BeEmpty()) + }) + + It("returns an error when an identity fields empty", func() { + hash, err := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash([]string{"alpha", "", "charlie"}) + Expect(err).To(MatchError("identity field is empty")) + Expect(hash).To(BeEmpty()) + }) + + It("successfully returns same hash as legacy smbg expects", func() { + Expect(dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash([]string{"smbg", "tools", "2014-06-11T11:12:43.029Z", "5.550747991045533"})).To(Equal("e2ihon9nqcro96c4uugb4ftdnr07nqok")) + }) + + It("successfully returns same hash as legacy basal expects", func() { + Expect(dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash([]string{"basal", "scheduled", "tools", "2014-06-11T06:00:00.000Z"})).To(Equal("cjou7vscvp8ogv34d6vejootulqfn3jd")) + }) + + It("successfully returns same hash as legacy cbg expects", func() { + Expect(dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash([]string{"cbg", "DexHealthKit_Dexcom:com.dexcom.Share2:3.0.4.17", "2015-12-21T11:23:08Z"})).To(Equal("nsikjhfaprplpq78hc7di2lu5qpt1e3k")) + }) + }) }) diff --git a/data/service/service/standard.go b/data/service/service/standard.go index 4d7968336d..4fd370ab8e 100644 --- a/data/service/service/standard.go +++ b/data/service/service/standard.go @@ -203,6 +203,13 @@ func (s *Standard) initializeDataDeduplicatorFactory() error { s.Logger().Debug("Creating device truncate data set deduplicator") + deviceDeactivateLegacyHashDeduplicator, err := dataDeduplicatorDeduplicator.NewDeviceDeactivateLegacyHash() + if err != nil { + return errors.Wrap(err, "unable to create device deactivate legacy hash deduplicator") + } + + s.Logger().Debug("Creating device truncate data set deduplicator") + deviceTruncateDataSetDeduplicator, err := dataDeduplicatorDeduplicator.NewDeviceTruncateDataSet() if err != nil { return errors.Wrap(err, "unable to create device truncate data set deduplicator") @@ -229,6 +236,7 @@ func (s *Standard) initializeDataDeduplicatorFactory() error { deviceTruncateDataSetDeduplicator, dataSetDeleteOriginDeduplicator, noneDeduplicator, + deviceDeactivateLegacyHashDeduplicator, } factory, err := dataDeduplicatorFactory.New(deduplicators) diff --git a/data/test/datum.go b/data/test/datum.go index 97bd5c79d6..d0955bcb1c 100644 --- a/data/test/datum.go +++ b/data/test/datum.go @@ -16,6 +16,11 @@ type IdentityFieldsOutput struct { Error error } +type LegacyIdentityFieldsOutput struct { + LegacyIdentityFields []string + Error error +} + type Datum struct { MetaInvocations int MetaOutputs []interface{} @@ -27,6 +32,8 @@ type Datum struct { NormalizeInputs []data.Normalizer IdentityFieldsInvocations int IdentityFieldsOutputs []IdentityFieldsOutput + LegacyIdentityFieldsInvocations int + LegacyIdentityFieldsOutputs []LegacyIdentityFieldsOutput GetPayloadInvocations int GetPayloadOutputs []*metadata.Metadata GetOriginInvocations int @@ -108,6 +115,16 @@ func (d *Datum) IdentityFields() ([]string, error) { return output.IdentityFields, output.Error } +func (d *Datum) LegacyIdentityFields() ([]string, error) { + d.LegacyIdentityFieldsInvocations++ + + gomega.Expect(d.LegacyIdentityFieldsOutputs).ToNot(gomega.BeEmpty()) + + output := d.LegacyIdentityFieldsOutputs[0] + d.LegacyIdentityFieldsOutputs = d.LegacyIdentityFieldsOutputs[1:] + return output.LegacyIdentityFields, output.Error +} + func (d *Datum) GetPayload() *metadata.Metadata { d.GetPayloadInvocations++ diff --git a/data/types/activity/physical/physical.go b/data/types/activity/physical/physical.go index da184eb00e..e7b342b9e4 100644 --- a/data/types/activity/physical/physical.go +++ b/data/types/activity/physical/physical.go @@ -1,6 +1,8 @@ package physical import ( + "errors" + "github.com/tidepool-org/platform/data" "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/structure" @@ -296,3 +298,27 @@ func (p *Physical) Normalize(normalizer data.Normalizer) { p.Step.Normalize(normalizer.WithReference("step")) } } + +func (p *Physical) LegacyIdentityFields() ([]string, error) { + identityFields, err := p.Base.LegacyIdentityFields() + if err != nil { + return nil, err + } + + if p.DeviceID == nil { + return nil, errors.New("device id is missing") + } + + if *p.DeviceID == "" { + return nil, errors.New("device id is empty") + } + if p.Time == nil { + return nil, errors.New("time is missing") + } + + if (*p.Time).IsZero() { + return nil, errors.New("time is empty") + } + + return append(identityFields, *p.DeviceID, (*p.Time).Format(types.LegacyFieldTimeFormat)), nil +} diff --git a/data/types/activity/physical/physical_test.go b/data/types/activity/physical/physical_test.go index 7b81e4f682..a06614580a 100644 --- a/data/types/activity/physical/physical_test.go +++ b/data/types/activity/physical/physical_test.go @@ -1,6 +1,8 @@ package physical_test import ( + "time" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -1362,5 +1364,47 @@ var _ = Describe("Physical", func() { ), ) }) + + Context("LegacyIdentityFields", func() { + var datum *physical.Physical + + BeforeEach(func() { + datum = NewPhysical() + }) + + It("returns error if device id is missing", func() { + datum.DeviceID = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("device id is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if device id is empty", func() { + datum.DeviceID = pointer.FromString("") + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("device id is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is missing", func() { + datum.Time = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("time is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is empty", func() { + datum.Time = &time.Time{} + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("time is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns the expected legacy identity fields", func() { + legacyIdentityFields, err := datum.LegacyIdentityFields() + Expect(err).ToNot(HaveOccurred()) + Expect(legacyIdentityFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat)})) + }) + }) }) }) diff --git a/data/types/basal/basal.go b/data/types/basal/basal.go index 6e5892ce09..7f8467b779 100644 --- a/data/types/basal/basal.go +++ b/data/types/basal/basal.go @@ -63,6 +63,35 @@ func (b *Basal) IdentityFields() ([]string, error) { return append(identityFields, b.DeliveryType), nil } +func (b *Basal) LegacyIdentityFields() ([]string, error) { + identityFields, err := b.Base.LegacyIdentityFields() + if err != nil { + return nil, err + } + + if b.DeliveryType == "" { + return nil, errors.New("delivery type is empty") + } + + if b.DeviceID == nil { + return nil, errors.New("device id is missing") + } + + if *b.DeviceID == "" { + return nil, errors.New("device id is empty") + } + + if b.Time == nil { + return nil, errors.New("time is missing") + } + + if (*b.Time).IsZero() { + return nil, errors.New("time is empty") + } + + return append(identityFields, b.DeliveryType, *b.DeviceID, (*b.Time).Format(types.LegacyFieldTimeFormat)), nil +} + func ParseDeliveryType(parser structure.ObjectParser) *string { if !parser.Exists() { return nil diff --git a/data/types/basal/basal_test.go b/data/types/basal/basal_test.go index 7b9ecc1970..197b87ca0e 100644 --- a/data/types/basal/basal_test.go +++ b/data/types/basal/basal_test.go @@ -6,6 +6,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/data/types/basal" dataTypesBasalTest "github.com/tidepool-org/platform/data/types/basal/test" dataTypesTest "github.com/tidepool-org/platform/data/types/test" @@ -125,6 +126,54 @@ var _ = Describe("Basal", func() { Expect(identityFields).To(Equal([]string{*datum.UserID, *datum.DeviceID, (*datum.Time).Format(ExpectedTimeFormat), datum.Type, datum.DeliveryType})) }) }) + Context("LegacyIdentityFields", func() { + var datum *basal.Basal + + BeforeEach(func() { + datum = dataTypesBasalTest.RandomBasal() + }) + + It("returns error if delivery type is empty", func() { + datum.DeliveryType = "" + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("delivery type is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if device id is missing", func() { + datum.DeviceID = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("device id is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if device id is empty", func() { + datum.DeviceID = pointer.FromString("") + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("device id is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is missing", func() { + datum.Time = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("time is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is empty", func() { + datum.Time = &time.Time{} + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("time is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns the expected legacy identity fields", func() { + legacyIdentityFields, err := datum.LegacyIdentityFields() + Expect(err).ToNot(HaveOccurred()) + Expect(legacyIdentityFields).To(Equal([]string{datum.Type, datum.DeliveryType, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat)})) + }) + }) }) Context("ParseDeliveryType", func() { diff --git a/data/types/base.go b/data/types/base.go index c7a814ceb4..6c624ee25e 100644 --- a/data/types/base.go +++ b/data/types/base.go @@ -25,6 +25,7 @@ const ( TagLengthMaximum = 100 TagsLengthMaximum = 100 TimeFormat = time.RFC3339Nano + LegacyFieldTimeFormat = "2006-01-02T15:04:05.999+07:00" TimeZoneOffsetMaximum = 7 * 24 * 60 // TODO: Fix! Limit to reasonable values TimeZoneOffsetMinimum = -7 * 24 * 60 // TODO: Fix! Limit to reasonable values VersionInternalMinimum = 0 @@ -263,6 +264,13 @@ func (b *Base) IdentityFields() ([]string, error) { return []string{*b.UserID, *b.DeviceID, (*b.Time).Format(TimeFormat), b.Type}, nil } +func (b *Base) LegacyIdentityFields() ([]string, error) { + if b.Type == "" { + return nil, errors.New("type is empty") + } + return []string{b.Type}, nil +} + func (b *Base) GetOrigin() *origin.Origin { return b.Origin } diff --git a/data/types/base_test.go b/data/types/base_test.go index 4fb06705d6..4fa5623c7e 100644 --- a/data/types/base_test.go +++ b/data/types/base_test.go @@ -966,6 +966,22 @@ var _ = Describe("Base", func() { }) }) + Context("LegacyIdentityFields", func() { + + It("returns error if type is empty", func() { + datum.Type = "" + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("type is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns the expected legacy identity fields", func() { + identityFields, err := datum.LegacyIdentityFields() + Expect(err).ToNot(HaveOccurred()) + Expect(identityFields).To(Equal([]string{datum.Type})) + }) + }) + Context("GetPayload", func() { It("gets the payload", func() { Expect(datum.GetPayload()).To(Equal(datum.Payload)) diff --git a/data/types/blood/blood.go b/data/types/blood/blood.go index 174c252ffc..bd817c12af 100644 --- a/data/types/blood/blood.go +++ b/data/types/blood/blood.go @@ -43,3 +43,28 @@ func (b *Blood) IdentityFields() ([]string, error) { return append(identityFields, *b.Units, strconv.FormatFloat(*b.Value, 'f', -1, 64)), nil } + +func (b *Blood) LegacyIdentityFields() ([]string, error) { + identityFields, err := b.Base.LegacyIdentityFields() + if err != nil { + return nil, err + } + + if b.DeviceID == nil { + return nil, errors.New("device id is missing") + } + + if *b.DeviceID == "" { + return nil, errors.New("device id is empty") + } + + if b.Time == nil { + return nil, errors.New("time is missing") + } + + if (*b.Time).IsZero() { + return nil, errors.New("time is empty") + } + + return append(identityFields, *b.DeviceID, (*b.Time).Format(types.LegacyFieldTimeFormat)), nil +} diff --git a/data/types/blood/blood_test.go b/data/types/blood/blood_test.go index 6e933c26d7..0816836f79 100644 --- a/data/types/blood/blood_test.go +++ b/data/types/blood/blood_test.go @@ -128,5 +128,48 @@ var _ = Describe("Blood", func() { Expect(identityFields).To(Equal([]string{*datum.UserID, *datum.DeviceID, (*datum.Time).Format(ExpectedTimeFormat), datum.Type, *datum.Units, strconv.FormatFloat(*datum.Value, 'f', -1, 64)})) }) }) + + Context("LegacyIdentityFields", func() { + var datum *blood.Blood + + BeforeEach(func() { + datum = dataTypesBloodTest.NewBlood() + }) + + It("returns error if device id is missing", func() { + datum.DeviceID = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("device id is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if device id is empty", func() { + datum.DeviceID = pointer.FromString("") + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("device id is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is missing", func() { + datum.Time = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("time is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is empty", func() { + datum.Time = &time.Time{} + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("time is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns the expected legacy identity fields", func() { + legacyIdentityFields, err := datum.LegacyIdentityFields() + Expect(err).ToNot(HaveOccurred()) + Expect(legacyIdentityFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat)})) + }) + }) + }) }) diff --git a/data/types/blood/glucose/selfmonitored/selfmonitored.go b/data/types/blood/glucose/selfmonitored/selfmonitored.go index 303c7ef4e2..5b916d0f28 100644 --- a/data/types/blood/glucose/selfmonitored/selfmonitored.go +++ b/data/types/blood/glucose/selfmonitored/selfmonitored.go @@ -1,6 +1,9 @@ package selfmonitored import ( + "errors" + "strconv" + "github.com/tidepool-org/platform/data" "github.com/tidepool-org/platform/data/types/blood/glucose" "github.com/tidepool-org/platform/structure" @@ -65,3 +68,16 @@ func (s *SelfMonitored) Normalize(normalizer data.Normalizer) { s.Glucose.Normalize(normalizer) } + +func (s *SelfMonitored) LegacyIdentityFields() ([]string, error) { + identityFields, err := s.Blood.LegacyIdentityFields() + if err != nil { + return nil, err + } + + if s.Value == nil { + return nil, errors.New("value is missing") + } + + return append(identityFields, strconv.FormatFloat(*s.Value, 'f', -1, 64)), nil +} diff --git a/data/types/blood/glucose/selfmonitored/selfmonitored_test.go b/data/types/blood/glucose/selfmonitored/selfmonitored_test.go index 8e1ec05f96..993ddbd7c8 100644 --- a/data/types/blood/glucose/selfmonitored/selfmonitored_test.go +++ b/data/types/blood/glucose/selfmonitored/selfmonitored_test.go @@ -1,6 +1,9 @@ package selfmonitored_test import ( + "strconv" + "time" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -478,5 +481,54 @@ var _ = Describe("SelfMonitored", func() { ), ) }) + + Context("LegacyIdentityFields", func() { + var datum *selfmonitored.SelfMonitored + + BeforeEach(func() { + datum = NewSelfMonitored(pointer.FromString("mmol/l")) + }) + + It("returns error if device id is missing", func() { + datum.DeviceID = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("device id is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if device id is empty", func() { + datum.DeviceID = pointer.FromString("") + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("device id is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is missing", func() { + datum.Time = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("time is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is empty", func() { + datum.Time = &time.Time{} + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("time is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if value is missing", func() { + datum.Value = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("value is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns the expected legacy identity fields", func() { + legacyIdentityFields, err := datum.LegacyIdentityFields() + Expect(err).ToNot(HaveOccurred()) + Expect(legacyIdentityFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat), strconv.FormatFloat(*datum.Value, 'f', -1, 64)})) + }) + }) }) }) diff --git a/data/types/bolus/bolus.go b/data/types/bolus/bolus.go index fe969bb338..01d7ab33b7 100644 --- a/data/types/bolus/bolus.go +++ b/data/types/bolus/bolus.go @@ -79,3 +79,32 @@ func (b *Bolus) IdentityFields() ([]string, error) { return append(identityFields, b.SubType), nil } + +func (b *Bolus) LegacyIdentityFields() ([]string, error) { + identityFields, err := b.Base.LegacyIdentityFields() + if err != nil { + return nil, err + } + + if b.SubType == "" { + return nil, errors.New("sub type is empty") + } + + if b.DeviceID == nil { + return nil, errors.New("device id is missing") + } + + if *b.DeviceID == "" { + return nil, errors.New("device id is empty") + } + + if b.Time == nil { + return nil, errors.New("time is missing") + } + + if (*b.Time).IsZero() { + return nil, errors.New("time is empty") + } + + return append(identityFields, b.SubType, *b.DeviceID, (*b.Time).Format(types.LegacyFieldTimeFormat)), nil +} diff --git a/data/types/bolus/bolus_test.go b/data/types/bolus/bolus_test.go index 9a45140908..dd181cd060 100644 --- a/data/types/bolus/bolus_test.go +++ b/data/types/bolus/bolus_test.go @@ -7,6 +7,7 @@ import ( . "github.com/onsi/gomega" dataNormalizer "github.com/tidepool-org/platform/data/normalizer" + "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/data/types/bolus" dataTypesBolusTest "github.com/tidepool-org/platform/data/types/bolus/test" dataTypesInsulinTest "github.com/tidepool-org/platform/data/types/insulin/test" @@ -176,5 +177,54 @@ var _ = Describe("Bolus", func() { Expect(identityFields).To(Equal([]string{*datum.UserID, *datum.DeviceID, (*datum.Time).Format(ExpectedTimeFormat), datum.Type, datum.SubType})) }) }) + + Context("LegacyIdentityFields", func() { + var datum *bolus.Bolus + + BeforeEach(func() { + datum = dataTypesBolusTest.RandomBolus() + }) + + It("returns error if sub type is empty", func() { + datum.SubType = "" + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("sub type is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if device id is missing", func() { + datum.DeviceID = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("device id is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if device id is empty", func() { + datum.DeviceID = pointer.FromString("") + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("device id is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is missing", func() { + datum.Time = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("time is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is empty", func() { + datum.Time = &time.Time{} + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("time is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns the expected legacy identity fields", func() { + legacyIdentityFields, err := datum.LegacyIdentityFields() + Expect(err).ToNot(HaveOccurred()) + Expect(legacyIdentityFields).To(Equal([]string{datum.Type, datum.SubType, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat)})) + }) + }) }) }) diff --git a/data/types/device/device.go b/data/types/device/device.go index 3da51cb06e..5467fb39ae 100644 --- a/data/types/device/device.go +++ b/data/types/device/device.go @@ -57,3 +57,32 @@ func (d *Device) IdentityFields() ([]string, error) { return append(identityFields, d.SubType), nil } + +func (d *Device) LegacyIdentityFields() ([]string, error) { + identityFields, err := d.Base.LegacyIdentityFields() + if err != nil { + return nil, err + } + + if d.SubType == "" { + return nil, errors.New("sub type is empty") + } + + if d.Time == nil { + return nil, errors.New("time is missing") + } + + if (*d.Time).IsZero() { + return nil, errors.New("time is empty") + } + + if d.DeviceID == nil { + return nil, errors.New("device id is missing") + } + + if *d.DeviceID == "" { + return nil, errors.New("device id is empty") + } + + return append(identityFields, d.SubType, (*d.Time).Format(types.LegacyFieldTimeFormat), *d.DeviceID), nil +} diff --git a/data/types/device/device_test.go b/data/types/device/device_test.go index a46b013f96..edd0f3f663 100644 --- a/data/types/device/device_test.go +++ b/data/types/device/device_test.go @@ -6,6 +6,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/data/types/device" dataTypesDeviceTest "github.com/tidepool-org/platform/data/types/device/test" dataTypesTest "github.com/tidepool-org/platform/data/types/test" @@ -125,5 +126,54 @@ var _ = Describe("Device", func() { Expect(identityFields).To(Equal([]string{*datum.UserID, *datum.DeviceID, (*datum.Time).Format(ExpectedTimeFormat), datum.Type, datum.SubType})) }) }) + + Context("LegacyIdentityFields", func() { + var datum *device.Device + + BeforeEach(func() { + datum = dataTypesDeviceTest.RandomDevice() + }) + + It("returns error if sub type is empty", func() { + datum.SubType = "" + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("sub type is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if device id is missing", func() { + datum.DeviceID = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("device id is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if device id is empty", func() { + datum.DeviceID = pointer.FromString("") + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("device id is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is missing", func() { + datum.Time = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("time is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is empty", func() { + datum.Time = &time.Time{} + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("time is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns the expected legacy identity fields", func() { + legacyIdentityFields, err := datum.LegacyIdentityFields() + Expect(err).ToNot(HaveOccurred()) + Expect(legacyIdentityFields).To(Equal([]string{datum.Type, datum.SubType, (*datum.Time).Format(types.LegacyFieldTimeFormat), *datum.DeviceID})) + }) + }) }) }) diff --git a/data/types/food/food.go b/data/types/food/food.go index 41734f963f..ab4a99599f 100644 --- a/data/types/food/food.go +++ b/data/types/food/food.go @@ -1,6 +1,8 @@ package food import ( + "errors" + "github.com/tidepool-org/platform/data" "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/structure" @@ -104,3 +106,27 @@ func (f *Food) Normalize(normalizer data.Normalizer) { f.Base.Normalize(normalizer) } + +func (f *Food) LegacyIdentityFields() ([]string, error) { + identityFields, err := f.Base.LegacyIdentityFields() + if err != nil { + return nil, err + } + + if f.DeviceID == nil { + return nil, errors.New("device id is missing") + } + + if *f.DeviceID == "" { + return nil, errors.New("device id is empty") + } + if f.Time == nil { + return nil, errors.New("time is missing") + } + + if (*f.Time).IsZero() { + return nil, errors.New("time is empty") + } + + return append(identityFields, *f.DeviceID, (*f.Time).Format(types.LegacyFieldTimeFormat)), nil +} diff --git a/data/types/food/food_test.go b/data/types/food/food_test.go index bbf1dcdbea..330ff0b950 100644 --- a/data/types/food/food_test.go +++ b/data/types/food/food_test.go @@ -1,11 +1,15 @@ package food_test import ( + "time" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" dataNormalizer "github.com/tidepool-org/platform/data/normalizer" + "github.com/tidepool-org/platform/data/types" dataTypes "github.com/tidepool-org/platform/data/types" + "github.com/tidepool-org/platform/data/types/food" dataTypesFood "github.com/tidepool-org/platform/data/types/food" dataTypesFoodTest "github.com/tidepool-org/platform/data/types/food/test" dataTypesTest "github.com/tidepool-org/platform/data/types/test" @@ -431,5 +435,47 @@ var _ = Describe("Food", func() { ), ) }) + + Context("LegacyIdentityFields", func() { + var datum *food.Food + + BeforeEach(func() { + datum = dataTypesFoodTest.RandomFood(3) + }) + + It("returns error if device id is missing", func() { + datum.DeviceID = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("device id is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if device id is empty", func() { + datum.DeviceID = pointer.FromString("") + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("device id is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is missing", func() { + datum.Time = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("time is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is empty", func() { + datum.Time = &time.Time{} + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("time is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns the expected legacy identity fields", func() { + legacyIdentityFields, err := datum.LegacyIdentityFields() + Expect(err).ToNot(HaveOccurred()) + Expect(legacyIdentityFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat)})) + }) + }) }) }) diff --git a/data/types/insulin/insulin.go b/data/types/insulin/insulin.go index 00198cfac3..42c34b1cd2 100644 --- a/data/types/insulin/insulin.go +++ b/data/types/insulin/insulin.go @@ -1,6 +1,8 @@ package insulin import ( + "errors" + "github.com/tidepool-org/platform/data" "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/structure" @@ -72,3 +74,27 @@ func (i *Insulin) Normalize(normalizer data.Normalizer) { i.Formulation.Normalize(normalizer.WithReference("formulation")) } } + +func (i *Insulin) LegacyIdentityFields() ([]string, error) { + identityFields, err := i.Base.LegacyIdentityFields() + if err != nil { + return nil, err + } + + if i.DeviceID == nil { + return nil, errors.New("device id is missing") + } + + if *i.DeviceID == "" { + return nil, errors.New("device id is empty") + } + if i.Time == nil { + return nil, errors.New("time is missing") + } + + if (*i.Time).IsZero() { + return nil, errors.New("time is empty") + } + + return append(identityFields, *i.DeviceID, (*i.Time).Format(types.LegacyFieldTimeFormat)), nil +} diff --git a/data/types/insulin/insulin_test.go b/data/types/insulin/insulin_test.go index fcb714eaa3..5d5f3f6f48 100644 --- a/data/types/insulin/insulin_test.go +++ b/data/types/insulin/insulin_test.go @@ -1,6 +1,8 @@ package insulin_test import ( + "time" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -166,5 +168,47 @@ var _ = Describe("Insulin", func() { ), ) }) + + Context("LegacyIdentityFields", func() { + var datum *insulin.Insulin + + BeforeEach(func() { + datum = NewInsulin() + }) + + It("returns error if device id is missing", func() { + datum.DeviceID = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("device id is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if device id is empty", func() { + datum.DeviceID = pointer.FromString("") + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("device id is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is missing", func() { + datum.Time = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("time is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is empty", func() { + datum.Time = &time.Time{} + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("time is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns the expected legacy identity fields", func() { + legacyIdentityFields, err := datum.LegacyIdentityFields() + Expect(err).ToNot(HaveOccurred()) + Expect(legacyIdentityFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat)})) + }) + }) }) }) diff --git a/data/types/settings/cgm/cgm.go b/data/types/settings/cgm/cgm.go index a56223547c..c6745e8bfc 100644 --- a/data/types/settings/cgm/cgm.go +++ b/data/types/settings/cgm/cgm.go @@ -156,6 +156,31 @@ func (c *CGM) Normalize(normalizer data.Normalizer) { } } +func (c *CGM) LegacyIdentityFields() ([]string, error) { + identityFields, err := c.Base.LegacyIdentityFields() + if err != nil { + return nil, err + } + + if c.Time == nil { + return nil, errors.New("time is missing") + } + + if (*c.Time).IsZero() { + return nil, errors.New("time is empty") + } + + if c.DeviceID == nil { + return nil, errors.New("device id is missing") + } + + if *c.DeviceID == "" { + return nil, errors.New("device id is empty") + } + + return append(identityFields, (*c.Time).Format(dataTypes.LegacyFieldTimeFormat), *c.DeviceID), nil +} + func IsValidTransmitterID(value string) bool { return ValidateTransmitterID(value) == nil } diff --git a/data/types/settings/cgm/cgm_test.go b/data/types/settings/cgm/cgm_test.go index d6faa17627..8828f749ec 100644 --- a/data/types/settings/cgm/cgm_test.go +++ b/data/types/settings/cgm/cgm_test.go @@ -2,13 +2,16 @@ package cgm_test import ( "sort" + "time" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" dataBloodGlucoseTest "github.com/tidepool-org/platform/data/blood/glucose/test" dataNormalizer "github.com/tidepool-org/platform/data/normalizer" + "github.com/tidepool-org/platform/data/types" dataTypes "github.com/tidepool-org/platform/data/types" + "github.com/tidepool-org/platform/data/types/settings/cgm" dataTypesSettingsCgm "github.com/tidepool-org/platform/data/types/settings/cgm" dataTypesSettingsCgmTest "github.com/tidepool-org/platform/data/types/settings/cgm/test" dataTypesTest "github.com/tidepool-org/platform/data/types/test" @@ -594,6 +597,48 @@ var _ = Describe("CGM", func() { ), ) }) + + Context("LegacyIdentityFields", func() { + var datum *cgm.CGM + + BeforeEach(func() { + datum = dataTypesSettingsCgmTest.RandomCGM(pointer.FromString("mmol/l")) + }) + + It("returns error if device id is missing", func() { + datum.DeviceID = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("device id is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if device id is empty", func() { + datum.DeviceID = pointer.FromString("") + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("device id is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is missing", func() { + datum.Time = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("time is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is empty", func() { + datum.Time = &time.Time{} + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("time is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns the expected legacy identity fields", func() { + legacyIdentityFields, err := datum.LegacyIdentityFields() + Expect(err).ToNot(HaveOccurred()) + Expect(legacyIdentityFields).To(Equal([]string{datum.Type, (*datum.Time).Format(types.LegacyFieldTimeFormat), *datum.DeviceID})) + }) + }) }) Context("IsValidTransmitterID, TransmitterIDValidator, ValidateTransmitterID", func() { From 176ba6470ea278a6c7fcc0861633ca3294fb3748 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 29 May 2024 16:32:33 +1200 Subject: [PATCH 299/413] cleanup creation and tests for legacy id fields --- data/types/activity/physical/physical.go | 24 +----- data/types/activity/physical/physical_test.go | 37 +------- data/types/basal/basal.go | 29 +------ data/types/basal/basal_test.go | 28 ------ data/types/base.go | 71 +++++++++++++++- data/types/base_test.go | 85 +++++++++++++++++-- data/types/blood/blood.go | 23 +---- data/types/blood/blood_test.go | 35 +------- data/types/bolus/bolus.go | 29 +------ data/types/bolus/bolus_test.go | 28 ------ data/types/device/device.go | 29 +------ data/types/device/device_test.go | 28 ------ data/types/food/food.go | 24 +----- data/types/food/food_test.go | 38 +-------- data/types/insulin/insulin.go | 24 +----- data/types/insulin/insulin_test.go | 37 +------- data/types/settings/cgm/cgm.go | 23 +---- data/types/settings/cgm/cgm_test.go | 37 +------- 18 files changed, 166 insertions(+), 463 deletions(-) diff --git a/data/types/activity/physical/physical.go b/data/types/activity/physical/physical.go index e7b342b9e4..25839931f9 100644 --- a/data/types/activity/physical/physical.go +++ b/data/types/activity/physical/physical.go @@ -1,8 +1,6 @@ package physical import ( - "errors" - "github.com/tidepool-org/platform/data" "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/structure" @@ -300,25 +298,5 @@ func (p *Physical) Normalize(normalizer data.Normalizer) { } func (p *Physical) LegacyIdentityFields() ([]string, error) { - identityFields, err := p.Base.LegacyIdentityFields() - if err != nil { - return nil, err - } - - if p.DeviceID == nil { - return nil, errors.New("device id is missing") - } - - if *p.DeviceID == "" { - return nil, errors.New("device id is empty") - } - if p.Time == nil { - return nil, errors.New("time is missing") - } - - if (*p.Time).IsZero() { - return nil, errors.New("time is empty") - } - - return append(identityFields, *p.DeviceID, (*p.Time).Format(types.LegacyFieldTimeFormat)), nil + return types.NewLegacyIdentityBuilder(&p.Base, types.TypeDeviceIDTimeFormat).Build() } diff --git a/data/types/activity/physical/physical_test.go b/data/types/activity/physical/physical_test.go index a06614580a..ad9f08c128 100644 --- a/data/types/activity/physical/physical_test.go +++ b/data/types/activity/physical/physical_test.go @@ -1,8 +1,6 @@ package physical_test import ( - "time" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -1366,41 +1364,8 @@ var _ = Describe("Physical", func() { }) Context("LegacyIdentityFields", func() { - var datum *physical.Physical - - BeforeEach(func() { - datum = NewPhysical() - }) - - It("returns error if device id is missing", func() { - datum.DeviceID = nil - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("device id is missing")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if device id is empty", func() { - datum.DeviceID = pointer.FromString("") - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("device id is empty")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if time is missing", func() { - datum.Time = nil - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("time is missing")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if time is empty", func() { - datum.Time = &time.Time{} - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("time is empty")) - Expect(identityFields).To(BeEmpty()) - }) - It("returns the expected legacy identity fields", func() { + datum := NewPhysical() legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) Expect(legacyIdentityFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat)})) diff --git a/data/types/basal/basal.go b/data/types/basal/basal.go index 7f8467b779..6462bb572d 100644 --- a/data/types/basal/basal.go +++ b/data/types/basal/basal.go @@ -64,32 +64,9 @@ func (b *Basal) IdentityFields() ([]string, error) { } func (b *Basal) LegacyIdentityFields() ([]string, error) { - identityFields, err := b.Base.LegacyIdentityFields() - if err != nil { - return nil, err - } - - if b.DeliveryType == "" { - return nil, errors.New("delivery type is empty") - } - - if b.DeviceID == nil { - return nil, errors.New("device id is missing") - } - - if *b.DeviceID == "" { - return nil, errors.New("device id is empty") - } - - if b.Time == nil { - return nil, errors.New("time is missing") - } - - if (*b.Time).IsZero() { - return nil, errors.New("time is empty") - } - - return append(identityFields, b.DeliveryType, *b.DeviceID, (*b.Time).Format(types.LegacyFieldTimeFormat)), nil + builder := types.NewLegacyIdentityBuilder(&b.Base, types.TypeDeviceIDTimeFormat) + builder.SetExtra(&b.DeliveryType, "delivery type") + return builder.Build() } func ParseDeliveryType(parser structure.ObjectParser) *string { diff --git a/data/types/basal/basal_test.go b/data/types/basal/basal_test.go index 197b87ca0e..4efabd6275 100644 --- a/data/types/basal/basal_test.go +++ b/data/types/basal/basal_test.go @@ -140,34 +140,6 @@ var _ = Describe("Basal", func() { Expect(identityFields).To(BeEmpty()) }) - It("returns error if device id is missing", func() { - datum.DeviceID = nil - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("device id is missing")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if device id is empty", func() { - datum.DeviceID = pointer.FromString("") - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("device id is empty")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if time is missing", func() { - datum.Time = nil - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("time is missing")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if time is empty", func() { - datum.Time = &time.Time{} - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("time is empty")) - Expect(identityFields).To(BeEmpty()) - }) - It("returns the expected legacy identity fields", func() { legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) diff --git a/data/types/base.go b/data/types/base.go index 6c624ee25e..66411fe224 100644 --- a/data/types/base.go +++ b/data/types/base.go @@ -1,6 +1,7 @@ package types import ( + "fmt" "sort" "time" @@ -264,11 +265,75 @@ func (b *Base) IdentityFields() ([]string, error) { return []string{*b.UserID, *b.DeviceID, (*b.Time).Format(TimeFormat), b.Type}, nil } -func (b *Base) LegacyIdentityFields() ([]string, error) { - if b.Type == "" { +type LegacyIdentityFormat int + +const ( + _ LegacyIdentityFormat = iota + TypeDeviceIDTimeFormat + TypeTimeDeviceIDFormat +) + +type legacyIdentityBuilder struct { + base *Base + format LegacyIdentityFormat + extraValue *string + extraName string +} + +func NewLegacyIdentityBuilder(base *Base, format LegacyIdentityFormat) *legacyIdentityBuilder { + return &legacyIdentityBuilder{ + base: base, + format: format, + } +} + +func (b *legacyIdentityBuilder) SetExtra(val *string, name string) *legacyIdentityBuilder { + b.extraValue = val + b.extraName = name + return b +} + +func (b *legacyIdentityBuilder) Build() ([]string, error) { + if b.base.Type == "" { return nil, errors.New("type is empty") } - return []string{b.Type}, nil + + if b.base.DeviceID == nil { + return nil, errors.New("device id is missing") + } + + if *b.base.DeviceID == "" { + return nil, errors.New("device id is empty") + } + + if b.base.Time == nil { + return nil, errors.New("time is missing") + } + + if (*b.base.Time).IsZero() { + return nil, errors.New("time is empty") + } + + if b.extraValue != nil { + if *b.extraValue == "" { + return nil, fmt.Errorf("%s is empty", b.extraName) + } + } + if b.format == TypeDeviceIDTimeFormat { + if b.extraValue != nil { + return []string{b.base.Type, *b.extraValue, *b.base.DeviceID, (*b.base.Time).Format(LegacyFieldTimeFormat)}, nil + } + return []string{b.base.Type, *b.base.DeviceID, (*b.base.Time).Format(LegacyFieldTimeFormat)}, nil + } + if b.extraValue != nil { + return []string{b.base.Type, *b.extraValue, (*b.base.Time).Format(LegacyFieldTimeFormat), *b.base.DeviceID}, nil + } + return []string{b.base.Type, (*b.base.Time).Format(LegacyFieldTimeFormat), *b.base.DeviceID}, nil + +} + +func (b *Base) LegacyIdentityFields() ([]string, error) { + return nil, errors.New("function must be implemented on data type") } func (b *Base) GetOrigin() *origin.Origin { diff --git a/data/types/base_test.go b/data/types/base_test.go index 4fa5623c7e..97d31c03e1 100644 --- a/data/types/base_test.go +++ b/data/types/base_test.go @@ -968,17 +968,88 @@ var _ = Describe("Base", func() { Context("LegacyIdentityFields", func() { - It("returns error if type is empty", func() { - datum.Type = "" + var datum *types.Base + + BeforeEach(func() { + datum = dataTypesTest.RandomBase() + }) + + It("returns error if not implemented", func() { identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("type is empty")) + Expect(err).To(MatchError("function must be implemented on data type")) Expect(identityFields).To(BeEmpty()) }) - It("returns the expected legacy identity fields", func() { - identityFields, err := datum.LegacyIdentityFields() - Expect(err).ToNot(HaveOccurred()) - Expect(identityFields).To(Equal([]string{datum.Type})) + Context("Builder", func() { + + It("returns error if type is empty", func() { + datum.Type = "" + identityFields, err := types.NewLegacyIdentityBuilder(datum, types.TypeTimeDeviceIDFormat).Build() + Expect(err).To(MatchError("type is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if device id is missing", func() { + datum.DeviceID = nil + identityFields, err := types.NewLegacyIdentityBuilder(datum, types.TypeTimeDeviceIDFormat).Build() + Expect(err).To(MatchError("device id is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if device id is empty", func() { + datum.DeviceID = pointer.FromString("") + identityFields, err := types.NewLegacyIdentityBuilder(datum, types.TypeTimeDeviceIDFormat).Build() + Expect(err).To(MatchError("device id is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is missing", func() { + datum.Time = nil + identityFields, err := types.NewLegacyIdentityBuilder(datum, types.TypeTimeDeviceIDFormat).Build() + Expect(err).To(MatchError("time is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if time is empty", func() { + datum.Time = &time.Time{} + identityFields, err := types.NewLegacyIdentityBuilder(datum, types.TypeTimeDeviceIDFormat).Build() + Expect(err).To(MatchError("time is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if extra is empty", func() { + builder := types.NewLegacyIdentityBuilder(datum, types.TypeTimeDeviceIDFormat) + builder.SetExtra(pointer.FromString(""), "delivery type") + identityFields, err := builder.Build() + Expect(err).To(MatchError("delivery type is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + Context("with TypeDeviceIDTimeLegacyIdentityFields", func() { + It("returns the expected legacy identity fields", func() { + identityFields, err := types.NewLegacyIdentityBuilder(datum, types.TypeDeviceIDTimeFormat).Build() + Expect(err).ToNot(HaveOccurred()) + Expect(identityFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat)})) + }) + }) + + Context("with TypeTimeDeviceIDLegacyIdentityFields", func() { + It("returns the expected legacy identity fields", func() { + identityFields, err := types.NewLegacyIdentityBuilder(datum, types.TypeTimeDeviceIDFormat).Build() + Expect(err).ToNot(HaveOccurred()) + Expect(identityFields).To(Equal([]string{datum.Type, (*datum.Time).Format(types.LegacyFieldTimeFormat), *datum.DeviceID})) + }) + }) + Context("with extra", func() { + It("returns the expected legacy identity fields", func() { + builder := types.NewLegacyIdentityBuilder(datum, types.TypeTimeDeviceIDFormat) + builder.SetExtra(pointer.FromString("some-sub-type"), "sub type") + + identityFields, err := builder.Build() + Expect(err).ToNot(HaveOccurred()) + Expect(identityFields).To(Equal([]string{datum.Type, "some-sub-type", (*datum.Time).Format(types.LegacyFieldTimeFormat), *datum.DeviceID})) + }) + }) }) }) diff --git a/data/types/blood/blood.go b/data/types/blood/blood.go index bd817c12af..dd48295d54 100644 --- a/data/types/blood/blood.go +++ b/data/types/blood/blood.go @@ -45,26 +45,5 @@ func (b *Blood) IdentityFields() ([]string, error) { } func (b *Blood) LegacyIdentityFields() ([]string, error) { - identityFields, err := b.Base.LegacyIdentityFields() - if err != nil { - return nil, err - } - - if b.DeviceID == nil { - return nil, errors.New("device id is missing") - } - - if *b.DeviceID == "" { - return nil, errors.New("device id is empty") - } - - if b.Time == nil { - return nil, errors.New("time is missing") - } - - if (*b.Time).IsZero() { - return nil, errors.New("time is empty") - } - - return append(identityFields, *b.DeviceID, (*b.Time).Format(types.LegacyFieldTimeFormat)), nil + return types.NewLegacyIdentityBuilder(&b.Base, types.TypeDeviceIDTimeFormat).Build() } diff --git a/data/types/blood/blood_test.go b/data/types/blood/blood_test.go index 0816836f79..75031c1b3d 100644 --- a/data/types/blood/blood_test.go +++ b/data/types/blood/blood_test.go @@ -130,41 +130,8 @@ var _ = Describe("Blood", func() { }) Context("LegacyIdentityFields", func() { - var datum *blood.Blood - - BeforeEach(func() { - datum = dataTypesBloodTest.NewBlood() - }) - - It("returns error if device id is missing", func() { - datum.DeviceID = nil - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("device id is missing")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if device id is empty", func() { - datum.DeviceID = pointer.FromString("") - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("device id is empty")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if time is missing", func() { - datum.Time = nil - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("time is missing")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if time is empty", func() { - datum.Time = &time.Time{} - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("time is empty")) - Expect(identityFields).To(BeEmpty()) - }) - It("returns the expected legacy identity fields", func() { + datum := dataTypesBloodTest.NewBlood() legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) Expect(legacyIdentityFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat)})) diff --git a/data/types/bolus/bolus.go b/data/types/bolus/bolus.go index 01d7ab33b7..f9cb73ed92 100644 --- a/data/types/bolus/bolus.go +++ b/data/types/bolus/bolus.go @@ -81,30 +81,7 @@ func (b *Bolus) IdentityFields() ([]string, error) { } func (b *Bolus) LegacyIdentityFields() ([]string, error) { - identityFields, err := b.Base.LegacyIdentityFields() - if err != nil { - return nil, err - } - - if b.SubType == "" { - return nil, errors.New("sub type is empty") - } - - if b.DeviceID == nil { - return nil, errors.New("device id is missing") - } - - if *b.DeviceID == "" { - return nil, errors.New("device id is empty") - } - - if b.Time == nil { - return nil, errors.New("time is missing") - } - - if (*b.Time).IsZero() { - return nil, errors.New("time is empty") - } - - return append(identityFields, b.SubType, *b.DeviceID, (*b.Time).Format(types.LegacyFieldTimeFormat)), nil + builder := types.NewLegacyIdentityBuilder(&b.Base, types.TypeDeviceIDTimeFormat) + builder.SetExtra(&b.SubType, "sub type") + return builder.Build() } diff --git a/data/types/bolus/bolus_test.go b/data/types/bolus/bolus_test.go index dd181cd060..61d98d12f1 100644 --- a/data/types/bolus/bolus_test.go +++ b/data/types/bolus/bolus_test.go @@ -192,34 +192,6 @@ var _ = Describe("Bolus", func() { Expect(identityFields).To(BeEmpty()) }) - It("returns error if device id is missing", func() { - datum.DeviceID = nil - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("device id is missing")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if device id is empty", func() { - datum.DeviceID = pointer.FromString("") - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("device id is empty")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if time is missing", func() { - datum.Time = nil - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("time is missing")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if time is empty", func() { - datum.Time = &time.Time{} - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("time is empty")) - Expect(identityFields).To(BeEmpty()) - }) - It("returns the expected legacy identity fields", func() { legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) diff --git a/data/types/device/device.go b/data/types/device/device.go index 5467fb39ae..c9426d045a 100644 --- a/data/types/device/device.go +++ b/data/types/device/device.go @@ -59,30 +59,7 @@ func (d *Device) IdentityFields() ([]string, error) { } func (d *Device) LegacyIdentityFields() ([]string, error) { - identityFields, err := d.Base.LegacyIdentityFields() - if err != nil { - return nil, err - } - - if d.SubType == "" { - return nil, errors.New("sub type is empty") - } - - if d.Time == nil { - return nil, errors.New("time is missing") - } - - if (*d.Time).IsZero() { - return nil, errors.New("time is empty") - } - - if d.DeviceID == nil { - return nil, errors.New("device id is missing") - } - - if *d.DeviceID == "" { - return nil, errors.New("device id is empty") - } - - return append(identityFields, d.SubType, (*d.Time).Format(types.LegacyFieldTimeFormat), *d.DeviceID), nil + builder := types.NewLegacyIdentityBuilder(&d.Base, types.TypeTimeDeviceIDFormat) + builder.SetExtra(&d.SubType, "sub type") + return builder.Build() } diff --git a/data/types/device/device_test.go b/data/types/device/device_test.go index edd0f3f663..a8067e5c90 100644 --- a/data/types/device/device_test.go +++ b/data/types/device/device_test.go @@ -141,34 +141,6 @@ var _ = Describe("Device", func() { Expect(identityFields).To(BeEmpty()) }) - It("returns error if device id is missing", func() { - datum.DeviceID = nil - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("device id is missing")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if device id is empty", func() { - datum.DeviceID = pointer.FromString("") - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("device id is empty")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if time is missing", func() { - datum.Time = nil - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("time is missing")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if time is empty", func() { - datum.Time = &time.Time{} - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("time is empty")) - Expect(identityFields).To(BeEmpty()) - }) - It("returns the expected legacy identity fields", func() { legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) diff --git a/data/types/food/food.go b/data/types/food/food.go index ab4a99599f..58cb0bbca7 100644 --- a/data/types/food/food.go +++ b/data/types/food/food.go @@ -1,8 +1,6 @@ package food import ( - "errors" - "github.com/tidepool-org/platform/data" "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/structure" @@ -108,25 +106,5 @@ func (f *Food) Normalize(normalizer data.Normalizer) { } func (f *Food) LegacyIdentityFields() ([]string, error) { - identityFields, err := f.Base.LegacyIdentityFields() - if err != nil { - return nil, err - } - - if f.DeviceID == nil { - return nil, errors.New("device id is missing") - } - - if *f.DeviceID == "" { - return nil, errors.New("device id is empty") - } - if f.Time == nil { - return nil, errors.New("time is missing") - } - - if (*f.Time).IsZero() { - return nil, errors.New("time is empty") - } - - return append(identityFields, *f.DeviceID, (*f.Time).Format(types.LegacyFieldTimeFormat)), nil + return types.NewLegacyIdentityBuilder(&f.Base, types.TypeDeviceIDTimeFormat).Build() } diff --git a/data/types/food/food_test.go b/data/types/food/food_test.go index 330ff0b950..c63c0559fe 100644 --- a/data/types/food/food_test.go +++ b/data/types/food/food_test.go @@ -1,15 +1,12 @@ package food_test import ( - "time" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" dataNormalizer "github.com/tidepool-org/platform/data/normalizer" "github.com/tidepool-org/platform/data/types" dataTypes "github.com/tidepool-org/platform/data/types" - "github.com/tidepool-org/platform/data/types/food" dataTypesFood "github.com/tidepool-org/platform/data/types/food" dataTypesFoodTest "github.com/tidepool-org/platform/data/types/food/test" dataTypesTest "github.com/tidepool-org/platform/data/types/test" @@ -437,41 +434,8 @@ var _ = Describe("Food", func() { }) Context("LegacyIdentityFields", func() { - var datum *food.Food - - BeforeEach(func() { - datum = dataTypesFoodTest.RandomFood(3) - }) - - It("returns error if device id is missing", func() { - datum.DeviceID = nil - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("device id is missing")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if device id is empty", func() { - datum.DeviceID = pointer.FromString("") - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("device id is empty")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if time is missing", func() { - datum.Time = nil - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("time is missing")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if time is empty", func() { - datum.Time = &time.Time{} - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("time is empty")) - Expect(identityFields).To(BeEmpty()) - }) - It("returns the expected legacy identity fields", func() { + datum := dataTypesFoodTest.RandomFood(3) legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) Expect(legacyIdentityFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat)})) diff --git a/data/types/insulin/insulin.go b/data/types/insulin/insulin.go index 42c34b1cd2..789dc0f7fe 100644 --- a/data/types/insulin/insulin.go +++ b/data/types/insulin/insulin.go @@ -1,8 +1,6 @@ package insulin import ( - "errors" - "github.com/tidepool-org/platform/data" "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/structure" @@ -76,25 +74,5 @@ func (i *Insulin) Normalize(normalizer data.Normalizer) { } func (i *Insulin) LegacyIdentityFields() ([]string, error) { - identityFields, err := i.Base.LegacyIdentityFields() - if err != nil { - return nil, err - } - - if i.DeviceID == nil { - return nil, errors.New("device id is missing") - } - - if *i.DeviceID == "" { - return nil, errors.New("device id is empty") - } - if i.Time == nil { - return nil, errors.New("time is missing") - } - - if (*i.Time).IsZero() { - return nil, errors.New("time is empty") - } - - return append(identityFields, *i.DeviceID, (*i.Time).Format(types.LegacyFieldTimeFormat)), nil + return types.NewLegacyIdentityBuilder(&i.Base, types.TypeDeviceIDTimeFormat).Build() } diff --git a/data/types/insulin/insulin_test.go b/data/types/insulin/insulin_test.go index 5d5f3f6f48..5d5ead6ac4 100644 --- a/data/types/insulin/insulin_test.go +++ b/data/types/insulin/insulin_test.go @@ -1,8 +1,6 @@ package insulin_test import ( - "time" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -170,41 +168,8 @@ var _ = Describe("Insulin", func() { }) Context("LegacyIdentityFields", func() { - var datum *insulin.Insulin - - BeforeEach(func() { - datum = NewInsulin() - }) - - It("returns error if device id is missing", func() { - datum.DeviceID = nil - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("device id is missing")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if device id is empty", func() { - datum.DeviceID = pointer.FromString("") - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("device id is empty")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if time is missing", func() { - datum.Time = nil - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("time is missing")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if time is empty", func() { - datum.Time = &time.Time{} - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("time is empty")) - Expect(identityFields).To(BeEmpty()) - }) - It("returns the expected legacy identity fields", func() { + datum := NewInsulin() legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) Expect(legacyIdentityFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat)})) diff --git a/data/types/settings/cgm/cgm.go b/data/types/settings/cgm/cgm.go index c6745e8bfc..f7c9885e31 100644 --- a/data/types/settings/cgm/cgm.go +++ b/data/types/settings/cgm/cgm.go @@ -157,28 +157,7 @@ func (c *CGM) Normalize(normalizer data.Normalizer) { } func (c *CGM) LegacyIdentityFields() ([]string, error) { - identityFields, err := c.Base.LegacyIdentityFields() - if err != nil { - return nil, err - } - - if c.Time == nil { - return nil, errors.New("time is missing") - } - - if (*c.Time).IsZero() { - return nil, errors.New("time is empty") - } - - if c.DeviceID == nil { - return nil, errors.New("device id is missing") - } - - if *c.DeviceID == "" { - return nil, errors.New("device id is empty") - } - - return append(identityFields, (*c.Time).Format(dataTypes.LegacyFieldTimeFormat), *c.DeviceID), nil + return dataTypes.NewLegacyIdentityBuilder(&c.Base, dataTypes.TypeTimeDeviceIDFormat).Build() } func IsValidTransmitterID(value string) bool { diff --git a/data/types/settings/cgm/cgm_test.go b/data/types/settings/cgm/cgm_test.go index 8828f749ec..b833eaa38b 100644 --- a/data/types/settings/cgm/cgm_test.go +++ b/data/types/settings/cgm/cgm_test.go @@ -2,7 +2,6 @@ package cgm_test import ( "sort" - "time" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -11,7 +10,6 @@ import ( dataNormalizer "github.com/tidepool-org/platform/data/normalizer" "github.com/tidepool-org/platform/data/types" dataTypes "github.com/tidepool-org/platform/data/types" - "github.com/tidepool-org/platform/data/types/settings/cgm" dataTypesSettingsCgm "github.com/tidepool-org/platform/data/types/settings/cgm" dataTypesSettingsCgmTest "github.com/tidepool-org/platform/data/types/settings/cgm/test" dataTypesTest "github.com/tidepool-org/platform/data/types/test" @@ -599,41 +597,10 @@ var _ = Describe("CGM", func() { }) Context("LegacyIdentityFields", func() { - var datum *cgm.CGM - - BeforeEach(func() { - datum = dataTypesSettingsCgmTest.RandomCGM(pointer.FromString("mmol/l")) - }) - - It("returns error if device id is missing", func() { - datum.DeviceID = nil - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("device id is missing")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if device id is empty", func() { - datum.DeviceID = pointer.FromString("") - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("device id is empty")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if time is missing", func() { - datum.Time = nil - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("time is missing")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if time is empty", func() { - datum.Time = &time.Time{} - identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("time is empty")) - Expect(identityFields).To(BeEmpty()) - }) It("returns the expected legacy identity fields", func() { + + datum := dataTypesSettingsCgmTest.RandomCGM(pointer.FromString("mmol/l")) legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) Expect(legacyIdentityFields).To(Equal([]string{datum.Type, (*datum.Time).Format(types.LegacyFieldTimeFormat), *datum.DeviceID})) From 0ba107ea1b481938f604e9a9d6f8b04b207c5082 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 30 May 2024 12:23:56 +1200 Subject: [PATCH 300/413] cleanup for getting of legacy fields --- data/types/activity/physical/physical.go | 2 +- data/types/basal/basal.go | 4 +- data/types/base.go | 55 +++++++++--------------- data/types/base_test.go | 31 ++++++------- data/types/blood/blood.go | 2 +- data/types/bolus/bolus.go | 4 +- data/types/device/device.go | 4 +- data/types/food/food.go | 2 +- data/types/insulin/insulin.go | 2 +- data/types/settings/cgm/cgm.go | 2 +- 10 files changed, 41 insertions(+), 67 deletions(-) diff --git a/data/types/activity/physical/physical.go b/data/types/activity/physical/physical.go index 25839931f9..f8951ec655 100644 --- a/data/types/activity/physical/physical.go +++ b/data/types/activity/physical/physical.go @@ -298,5 +298,5 @@ func (p *Physical) Normalize(normalizer data.Normalizer) { } func (p *Physical) LegacyIdentityFields() ([]string, error) { - return types.NewLegacyIdentityBuilder(&p.Base, types.TypeDeviceIDTimeFormat).Build() + return types.GetLegacyIdentityFields(&p.Base, types.TypeDeviceIDTimeFormat, nil) } diff --git a/data/types/basal/basal.go b/data/types/basal/basal.go index 6462bb572d..749c89653b 100644 --- a/data/types/basal/basal.go +++ b/data/types/basal/basal.go @@ -64,9 +64,7 @@ func (b *Basal) IdentityFields() ([]string, error) { } func (b *Basal) LegacyIdentityFields() ([]string, error) { - builder := types.NewLegacyIdentityBuilder(&b.Base, types.TypeDeviceIDTimeFormat) - builder.SetExtra(&b.DeliveryType, "delivery type") - return builder.Build() + return types.GetLegacyIdentityFields(&b.Base, types.TypeDeviceIDTimeFormat, &types.LegacyIdentityCustomField{Value: b.DeliveryType, Name: "delivery type"}) } func ParseDeliveryType(parser structure.ObjectParser) *string { diff --git a/data/types/base.go b/data/types/base.go index 66411fe224..e5dc49e737 100644 --- a/data/types/base.go +++ b/data/types/base.go @@ -273,63 +273,48 @@ const ( TypeTimeDeviceIDFormat ) -type legacyIdentityBuilder struct { - base *Base - format LegacyIdentityFormat - extraValue *string - extraName string +type LegacyIdentityCustomField struct { + Value string + Name string } -func NewLegacyIdentityBuilder(base *Base, format LegacyIdentityFormat) *legacyIdentityBuilder { - return &legacyIdentityBuilder{ - base: base, - format: format, - } -} - -func (b *legacyIdentityBuilder) SetExtra(val *string, name string) *legacyIdentityBuilder { - b.extraValue = val - b.extraName = name - return b -} - -func (b *legacyIdentityBuilder) Build() ([]string, error) { - if b.base.Type == "" { +func GetLegacyIdentityFields(base *Base, format LegacyIdentityFormat, opt *LegacyIdentityCustomField) ([]string, error) { + if base.Type == "" { return nil, errors.New("type is empty") } - if b.base.DeviceID == nil { + if base.DeviceID == nil { return nil, errors.New("device id is missing") } - if *b.base.DeviceID == "" { + if *base.DeviceID == "" { return nil, errors.New("device id is empty") } - if b.base.Time == nil { + if base.Time == nil { return nil, errors.New("time is missing") } - if (*b.base.Time).IsZero() { + if (*base.Time).IsZero() { return nil, errors.New("time is empty") } - if b.extraValue != nil { - if *b.extraValue == "" { - return nil, fmt.Errorf("%s is empty", b.extraName) + if opt != nil { + if opt.Value == "" { + return nil, fmt.Errorf("%s is empty", opt.Name) } } - if b.format == TypeDeviceIDTimeFormat { - if b.extraValue != nil { - return []string{b.base.Type, *b.extraValue, *b.base.DeviceID, (*b.base.Time).Format(LegacyFieldTimeFormat)}, nil + + if format == TypeDeviceIDTimeFormat { + if opt != nil { + return []string{base.Type, opt.Value, *base.DeviceID, (*base.Time).Format(LegacyFieldTimeFormat)}, nil } - return []string{b.base.Type, *b.base.DeviceID, (*b.base.Time).Format(LegacyFieldTimeFormat)}, nil + return []string{base.Type, *base.DeviceID, (*base.Time).Format(LegacyFieldTimeFormat)}, nil } - if b.extraValue != nil { - return []string{b.base.Type, *b.extraValue, (*b.base.Time).Format(LegacyFieldTimeFormat), *b.base.DeviceID}, nil + if opt != nil { + return []string{base.Type, opt.Value, (*base.Time).Format(LegacyFieldTimeFormat), *base.DeviceID}, nil } - return []string{b.base.Type, (*b.base.Time).Format(LegacyFieldTimeFormat), *b.base.DeviceID}, nil - + return []string{base.Type, (*base.Time).Format(LegacyFieldTimeFormat), *base.DeviceID}, nil } func (b *Base) LegacyIdentityFields() ([]string, error) { diff --git a/data/types/base_test.go b/data/types/base_test.go index 97d31c03e1..6633093c35 100644 --- a/data/types/base_test.go +++ b/data/types/base_test.go @@ -980,72 +980,67 @@ var _ = Describe("Base", func() { Expect(identityFields).To(BeEmpty()) }) - Context("Builder", func() { + Context("GetLegacyIdentityFields", func() { It("returns error if type is empty", func() { datum.Type = "" - identityFields, err := types.NewLegacyIdentityBuilder(datum, types.TypeTimeDeviceIDFormat).Build() + identityFields, err := types.GetLegacyIdentityFields(datum, types.TypeTimeDeviceIDFormat, nil) Expect(err).To(MatchError("type is empty")) Expect(identityFields).To(BeEmpty()) }) It("returns error if device id is missing", func() { datum.DeviceID = nil - identityFields, err := types.NewLegacyIdentityBuilder(datum, types.TypeTimeDeviceIDFormat).Build() + identityFields, err := types.GetLegacyIdentityFields(datum, types.TypeTimeDeviceIDFormat, nil) Expect(err).To(MatchError("device id is missing")) Expect(identityFields).To(BeEmpty()) }) It("returns error if device id is empty", func() { datum.DeviceID = pointer.FromString("") - identityFields, err := types.NewLegacyIdentityBuilder(datum, types.TypeTimeDeviceIDFormat).Build() + identityFields, err := types.GetLegacyIdentityFields(datum, types.TypeTimeDeviceIDFormat, nil) Expect(err).To(MatchError("device id is empty")) Expect(identityFields).To(BeEmpty()) }) It("returns error if time is missing", func() { datum.Time = nil - identityFields, err := types.NewLegacyIdentityBuilder(datum, types.TypeTimeDeviceIDFormat).Build() + identityFields, err := types.GetLegacyIdentityFields(datum, types.TypeTimeDeviceIDFormat, nil) Expect(err).To(MatchError("time is missing")) Expect(identityFields).To(BeEmpty()) }) It("returns error if time is empty", func() { datum.Time = &time.Time{} - identityFields, err := types.NewLegacyIdentityBuilder(datum, types.TypeTimeDeviceIDFormat).Build() + identityFields, err := types.GetLegacyIdentityFields(datum, types.TypeTimeDeviceIDFormat, nil) Expect(err).To(MatchError("time is empty")) Expect(identityFields).To(BeEmpty()) }) It("returns error if extra is empty", func() { - builder := types.NewLegacyIdentityBuilder(datum, types.TypeTimeDeviceIDFormat) - builder.SetExtra(pointer.FromString(""), "delivery type") - identityFields, err := builder.Build() + identityFields, err := types.GetLegacyIdentityFields(datum, types.TypeTimeDeviceIDFormat, &types.LegacyIdentityCustomField{Value: "", Name: "delivery type"}) Expect(err).To(MatchError("delivery type is empty")) Expect(identityFields).To(BeEmpty()) }) - Context("with TypeDeviceIDTimeLegacyIdentityFields", func() { + Context("with TypeDeviceIDTimeFormat", func() { It("returns the expected legacy identity fields", func() { - identityFields, err := types.NewLegacyIdentityBuilder(datum, types.TypeDeviceIDTimeFormat).Build() + identityFields, err := types.GetLegacyIdentityFields(datum, types.TypeDeviceIDTimeFormat, nil) Expect(err).ToNot(HaveOccurred()) Expect(identityFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat)})) }) }) - Context("with TypeTimeDeviceIDLegacyIdentityFields", func() { + Context("with TypeTimeDeviceIDFormat", func() { It("returns the expected legacy identity fields", func() { - identityFields, err := types.NewLegacyIdentityBuilder(datum, types.TypeTimeDeviceIDFormat).Build() + identityFields, err := types.GetLegacyIdentityFields(datum, types.TypeTimeDeviceIDFormat, nil) Expect(err).ToNot(HaveOccurred()) Expect(identityFields).To(Equal([]string{datum.Type, (*datum.Time).Format(types.LegacyFieldTimeFormat), *datum.DeviceID})) }) }) - Context("with extra", func() { + Context("with LegacyIdentityCustomField", func() { It("returns the expected legacy identity fields", func() { - builder := types.NewLegacyIdentityBuilder(datum, types.TypeTimeDeviceIDFormat) - builder.SetExtra(pointer.FromString("some-sub-type"), "sub type") - - identityFields, err := builder.Build() + identityFields, err := types.GetLegacyIdentityFields(datum, types.TypeTimeDeviceIDFormat, &types.LegacyIdentityCustomField{Value: "some-sub-type", Name: "sub type"}) Expect(err).ToNot(HaveOccurred()) Expect(identityFields).To(Equal([]string{datum.Type, "some-sub-type", (*datum.Time).Format(types.LegacyFieldTimeFormat), *datum.DeviceID})) }) diff --git a/data/types/blood/blood.go b/data/types/blood/blood.go index dd48295d54..16fea31116 100644 --- a/data/types/blood/blood.go +++ b/data/types/blood/blood.go @@ -45,5 +45,5 @@ func (b *Blood) IdentityFields() ([]string, error) { } func (b *Blood) LegacyIdentityFields() ([]string, error) { - return types.NewLegacyIdentityBuilder(&b.Base, types.TypeDeviceIDTimeFormat).Build() + return types.GetLegacyIdentityFields(&b.Base, types.TypeDeviceIDTimeFormat, nil) } diff --git a/data/types/bolus/bolus.go b/data/types/bolus/bolus.go index f9cb73ed92..99a6b83e56 100644 --- a/data/types/bolus/bolus.go +++ b/data/types/bolus/bolus.go @@ -81,7 +81,5 @@ func (b *Bolus) IdentityFields() ([]string, error) { } func (b *Bolus) LegacyIdentityFields() ([]string, error) { - builder := types.NewLegacyIdentityBuilder(&b.Base, types.TypeDeviceIDTimeFormat) - builder.SetExtra(&b.SubType, "sub type") - return builder.Build() + return types.GetLegacyIdentityFields(&b.Base, types.TypeDeviceIDTimeFormat, &types.LegacyIdentityCustomField{Value: b.SubType, Name: "sub type"}) } diff --git a/data/types/device/device.go b/data/types/device/device.go index c9426d045a..98ca37b775 100644 --- a/data/types/device/device.go +++ b/data/types/device/device.go @@ -59,7 +59,5 @@ func (d *Device) IdentityFields() ([]string, error) { } func (d *Device) LegacyIdentityFields() ([]string, error) { - builder := types.NewLegacyIdentityBuilder(&d.Base, types.TypeTimeDeviceIDFormat) - builder.SetExtra(&d.SubType, "sub type") - return builder.Build() + return types.GetLegacyIdentityFields(&d.Base, types.TypeTimeDeviceIDFormat, &types.LegacyIdentityCustomField{Value: d.SubType, Name: "sub type"}) } diff --git a/data/types/food/food.go b/data/types/food/food.go index 58cb0bbca7..8ed96720ee 100644 --- a/data/types/food/food.go +++ b/data/types/food/food.go @@ -106,5 +106,5 @@ func (f *Food) Normalize(normalizer data.Normalizer) { } func (f *Food) LegacyIdentityFields() ([]string, error) { - return types.NewLegacyIdentityBuilder(&f.Base, types.TypeDeviceIDTimeFormat).Build() + return types.GetLegacyIdentityFields(&f.Base, types.TypeDeviceIDTimeFormat, nil) } diff --git a/data/types/insulin/insulin.go b/data/types/insulin/insulin.go index 789dc0f7fe..0c810d95ba 100644 --- a/data/types/insulin/insulin.go +++ b/data/types/insulin/insulin.go @@ -74,5 +74,5 @@ func (i *Insulin) Normalize(normalizer data.Normalizer) { } func (i *Insulin) LegacyIdentityFields() ([]string, error) { - return types.NewLegacyIdentityBuilder(&i.Base, types.TypeDeviceIDTimeFormat).Build() + return types.GetLegacyIdentityFields(&i.Base, types.TypeDeviceIDTimeFormat, nil) } diff --git a/data/types/settings/cgm/cgm.go b/data/types/settings/cgm/cgm.go index f7c9885e31..becc27ac44 100644 --- a/data/types/settings/cgm/cgm.go +++ b/data/types/settings/cgm/cgm.go @@ -157,7 +157,7 @@ func (c *CGM) Normalize(normalizer data.Normalizer) { } func (c *CGM) LegacyIdentityFields() ([]string, error) { - return dataTypes.NewLegacyIdentityBuilder(&c.Base, dataTypes.TypeTimeDeviceIDFormat).Build() + return dataTypes.GetLegacyIdentityFields(&c.Base, dataTypes.TypeTimeDeviceIDFormat, nil) } func IsValidTransmitterID(value string) bool { From fb425d04dd0391b6310de581c7895500a5ff7479 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 5 Jun 2024 09:07:20 +1200 Subject: [PATCH 301/413] changes for migration of jellyfish upload records --- .../jellyfish_audit.sh | 3 - .../jellyfish_migration.go | 36 +- .../utils/data_migration.go | 60 +-- .../utils/data_migration_test.go | 94 ++-- .../utils/jellyfish_data.go | 115 +++-- .../utils/test/data.go | 374 ++------------ .../utils/utils.go | 472 ------------------ .../utils/utils_test.go | 455 ----------------- 8 files changed, 168 insertions(+), 1441 deletions(-) delete mode 100644 migrations/20231128_jellyfish_migration/jellyfish_audit.sh delete mode 100644 migrations/20231128_jellyfish_migration/utils/utils.go delete mode 100644 migrations/20231128_jellyfish_migration/utils/utils_test.go diff --git a/migrations/20231128_jellyfish_migration/jellyfish_audit.sh b/migrations/20231128_jellyfish_migration/jellyfish_audit.sh deleted file mode 100644 index af42d72f12..0000000000 --- a/migrations/20231128_jellyfish_migration/jellyfish_audit.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -go run jellyfish_migration.go --dry-run --cap=500000 --nop-percent=1 --query-limit=100 --query-batch=50 diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 7bb9679846..9c129d4a7b 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -24,17 +24,15 @@ type Migration struct { } type config struct { - cap int - uri string - dryRun bool - stopOnErr bool - rollback bool - rollbackSectionName string - userID string - lastUpdatedID string - nopPercent int - queryBatchSize int - queryLimit int + cap int + uri string + dryRun bool + stopOnErr bool + userID string + lastUpdatedID string + nopPercent int + queryBatchSize int + queryLimit int } const DryRunFlag = "dry-run" @@ -50,11 +48,9 @@ func main() { func NewJellyfishMigration(ctx context.Context) *Migration { return &Migration{ - config: &config{ - rollbackSectionName: "_rollbackJellyfishMigration", - }, - ctx: ctx, - cli: cli.NewApp(), + config: &config{}, + ctx: ctx, + cli: cli.NewApp(), } } @@ -62,7 +58,6 @@ func (c *config) report() string { details := "\nMIGRATION DETAILS:\n" details += fmt.Sprintf("- CAP\t\t\t[%d]\n", c.cap) details += fmt.Sprintf("- AUDIT? \t\t[%t]\n", c.dryRun) - details += fmt.Sprintf("- ROLLBACK\t\t[%t]\n", c.rollback) details += fmt.Sprintf("- STOP ON ERROR\t\t[%t]\n", c.stopOnErr) details += fmt.Sprintf("- LAST PROCESSED ID\t[%s]\n", c.lastUpdatedID) details += fmt.Sprintf("- USER ID\t\t[%s]\n", c.userID) @@ -95,8 +90,6 @@ func (m *Migration) RunAndExit() { utils.NewSettings( &m.config.dryRun, &m.config.stopOnErr, - &m.config.rollback, - &m.config.rollbackSectionName, &m.config.cap, &m.config.queryBatchSize, &m.config.queryLimit, @@ -152,11 +145,6 @@ func (m *Migration) Initialize() error { Usage: "stop migration on error", Destination: &m.config.stopOnErr, }, - cli.BoolFlag{ - Name: "rollback", - Usage: "rollback migration changes that have been applied", - Destination: &m.config.rollback, - }, cli.IntFlag{ Name: "cap", Usage: "max number of records migrate", diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go index 71acc16c37..4f05abd180 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration.go @@ -16,13 +16,9 @@ import ( ) type UpdateData struct { - Filter interface{} `json:"-"` - ItemID string `json:"_id"` - UserID string `json:"_userId"` - ItemType string `json:"-"` - Apply []bson.M `json:"apply"` - ApplyLast bson.M `json:"applyLast"` - Revert []bson.M `json:"revert"` + Filter interface{} `json:"-"` + ItemID string `json:"_id"` + Apply []bson.M `json:"apply"` } type ErrorData struct { @@ -41,27 +37,23 @@ type MigrationStats struct { } type Settings struct { - DryRun bool - Rollback bool - RollbackSectionName string - StopOnErr bool - WriteBatchSize *int64 - QueryBatchSize int - QueryBatchLimit int + DryRun bool + StopOnErr bool + WriteBatchSize *int64 + QueryBatchSize int + QueryBatchLimit int capacity *int writeToDisk bool } -func NewSettings(dryRun *bool, stopOnErr *bool, rollback *bool, rollbackSectionName *string, capacity *int, queryBatch *int, queryLimit *int, writeToDisk *bool) *Settings { +func NewSettings(dryRun *bool, stopOnErr *bool, capacity *int, queryBatch *int, queryLimit *int, writeToDisk *bool) *Settings { settings := &Settings{ - writeToDisk: false, - Rollback: true, - RollbackSectionName: "_rollbackMigration", - DryRun: true, - StopOnErr: true, - QueryBatchSize: 50, - QueryBatchLimit: 100, + writeToDisk: false, + DryRun: true, + StopOnErr: true, + QueryBatchSize: 50, + QueryBatchLimit: 100, } if dryRun != nil { settings.DryRun = *dryRun @@ -69,12 +61,7 @@ func NewSettings(dryRun *bool, stopOnErr *bool, rollback *bool, rollbackSectionN if stopOnErr != nil { settings.StopOnErr = *stopOnErr } - if rollback != nil { - settings.Rollback = *rollback - } - if rollbackSectionName != nil { - settings.RollbackSectionName = *rollbackSectionName - } + if writeToDisk != nil { settings.writeToDisk = *writeToDisk } @@ -188,7 +175,7 @@ func (m *DataMigration) Execute( return nil } -func (d UpdateData) getMongoUpdates(rollback bool, rollbackSectionName string) []mongo.WriteModel { +func (d UpdateData) getMongoUpdates() []mongo.WriteModel { updates := []mongo.WriteModel{} for _, u := range d.Apply { updateOp := mongo.NewUpdateOneModel() @@ -196,20 +183,11 @@ func (d UpdateData) getMongoUpdates(rollback bool, rollbackSectionName string) [ updateOp.SetUpdate(u) updates = append(updates, updateOp) } - updateOp := mongo.NewUpdateOneModel() - updateOp.Filter = d.Filter - if !rollback && len(d.Revert) > 0 { - updateOp.SetUpdate(bson.M{"$set": bson.M{rollbackSectionName: d.Revert}}) - } else if rollback { - updateOp.SetUpdate(bson.M{"$unset": bson.M{rollbackSectionName: ""}}) - } - updates = append(updates, updateOp) return updates } func (m *DataMigration) SetUpdates(data UpdateData) { - m.groupedDiffs[data.ItemType] = append(m.groupedDiffs[data.ItemType], data) - m.updates = append(m.updates, data.getMongoUpdates(m.settings.Rollback, m.settings.RollbackSectionName)...) + m.updates = append(m.updates, data.getMongoUpdates()...) } func (m *DataMigration) updatesApplied(updatedCount int) { @@ -243,8 +221,8 @@ func (m *DataMigration) SetLastProcessed(lastID string) { m.writeLastProcessed(m.lastUpdatedID) } -func (m *DataMigration) SetFetched(raw []bson.M) { - m.fetchedCount += len(raw) +func (m *DataMigration) UpdateFetchedCount() { + m.fetchedCount++ } func (m *DataMigration) GetStats() MigrationStats { diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration_test.go b/migrations/20231128_jellyfish_migration/utils/data_migration_test.go index 05973327cb..bdd527e025 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration_test.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration_test.go @@ -9,6 +9,7 @@ import ( "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" + "github.com/tidepool-org/platform/data/deduplicator/deduplicator" dataStoreMongo "github.com/tidepool-org/platform/data/store/mongo" platformLog "github.com/tidepool-org/platform/log" logTest "github.com/tidepool-org/platform/log/test" @@ -54,32 +55,23 @@ func setCollectionData(ctx context.Context, dataC *mongo.Collection, dataSetData var _ = Describe("back-37", func() { var _ = Describe("migrationUtil", func() { - var testData []map[string]interface{} + var testJFData []map[string]interface{} + var testJFUploads []map[string]interface{} const datumCount = 1000 + const uploadCount = 99 var store *dataStoreMongo.Store var ctx context.Context - var rollbackSettings *utils.Settings var migrationSettings *utils.Settings BeforeEach(func() { logger := logTest.NewLogger() ctx = platformLog.NewContextWithLogger(context.Background(), logger) - testData = test.BulkJellyfishData("test-device-88x89", "test-group-id", "test-user-id-123", datumCount) - rollbackSettings = utils.NewSettings( - pointer.FromBool(false), - pointer.FromBool(false), - pointer.FromBool(true), - pointer.FromString("_testRollback"), - nil, - pointer.FromInt(50), - pointer.FromInt(100), - pointer.FromBool(false), - ) + testJFData = test.BulkJellyfishData("test-device-88x89", "test-group-id", "test-user-id-123", datumCount) + testJFUploads = test.BulkJellyfishData("test-device-other", "test-group-id_2", "test-user-id-987", uploadCount) + migrationSettings = utils.NewSettings( pointer.FromBool(false), pointer.FromBool(false), - pointer.FromBool(false), - pointer.FromString("_testRollback"), nil, pointer.FromInt(50), pointer.FromInt(100), @@ -95,15 +87,15 @@ var _ = Describe("back-37", func() { _ = store.Terminate(ctx) } }) - It("apply migration will set _deduplicator and also rollback data", func() { - collection := store.GetCollection("testMigration") - Expect(setCollectionData(ctx, collection, testData)).To(Succeed()) + It("will set _deduplicator.hash to be the datum _id for jellyfish data", func() { + collection := store.GetCollection("testJFDatum") + Expect(setCollectionData(ctx, collection, testJFData)).To(Succeed()) migration, err := utils.NewMigration(ctx, migrationSettings, newMongoInstanceChecker(), collection, nil) Expect(err).To(BeNil()) - Expect(testData).ToNot(BeNil()) - Expect(len(testData)).To(Equal(datumCount)) + Expect(testJFData).ToNot(BeNil()) + Expect(len(testJFData)).To(Equal(datumCount)) allDocs, err := collection.CountDocuments(ctx, bson.D{}) Expect(err).To(BeNil()) Expect(allDocs).To(Equal(int64(datumCount))) @@ -111,10 +103,7 @@ var _ = Describe("back-37", func() { stats := migration.GetStats() Expect(stats.Errored).To(Equal(0)) Expect(stats.Fetched).To(Equal(datumCount)) - // There are 'at least' 2000 changes applied but we don't know the exact amount - // as it varies depending which types are included in the original data - Expect(stats.Applied > datumCount*2).To(BeTrue()) - + Expect(stats.Applied).To(Equal(datumCount)) cur, err := collection.Find(ctx, bson.D{}) Expect(err).To(BeNil()) migrated := []map[string]interface{}{} @@ -124,56 +113,41 @@ var _ = Describe("back-37", func() { for _, item := range migrated { Expect(item).Should(HaveKey("_deduplicator")) - Expect(item["_deduplicator"]).Should(HaveKey("hash")) - Expect(item).Should(HaveKey(migration.GetSettings().RollbackSectionName)) + Expect(item["_deduplicator"]).Should(HaveLen(1)) + Expect(item["_deduplicator"]).Should(HaveKeyWithValue("hash", item["_id"])) } - }) - It("apply then rollback migration will return the data to its orginal state", func() { - collection := store.GetCollection("testRollback") - Expect(setCollectionData(ctx, collection, testData)).To(Succeed()) - - findOptions := options.Find() - findOptions.SetSort(bson.D{{Key: "_id", Value: -1}}) + It("will set _deduplicator to be the datum _id for jellyfish uploads", func() { + collection := store.GetCollection("testJFUploads") + Expect(setCollectionData(ctx, collection, testJFUploads)).To(Succeed()) migration, err := utils.NewMigration(ctx, migrationSettings, newMongoInstanceChecker(), collection, nil) Expect(err).To(BeNil()) - Expect(testData).ToNot(BeNil()) - Expect(len(testData)).To(Equal(datumCount)) - - cur, err := collection.Find(ctx, bson.D{}, findOptions) + Expect(testJFUploads).ToNot(BeNil()) + Expect(len(testJFUploads)).To(Equal(uploadCount)) + allUploadDocs, err := collection.CountDocuments(ctx, bson.D{}) Expect(err).To(BeNil()) - - original := []map[string]interface{}{} - cur.All(ctx, &original) - Expect(len(original)).To(Equal(datumCount)) - - Expect(migration.Execute(utils.JellyfishDataQueryFn, utils.JellyfishDataUpdatesFn)).To(Succeed()) - - cur, err = collection.Find(ctx, bson.D{}, findOptions) + Expect(allUploadDocs).To(Equal(int64(uploadCount))) + Expect(migration.Execute(utils.JellyfishUploadQueryFn, utils.JellyfishDataUpdatesFn)).To(Succeed()) + stats := migration.GetStats() + Expect(stats.Errored).To(Equal(0)) + Expect(stats.Fetched).To(Equal(uploadCount)) + Expect(stats.Applied).To(Equal(uploadCount)) + cur, err := collection.Find(ctx, bson.D{}) Expect(err).To(BeNil()) migrated := []map[string]interface{}{} cur.All(ctx, &migrated) - Expect(len(migrated)).To(Equal(datumCount)) - rollback, err := utils.NewMigration(ctx, rollbackSettings, newMongoInstanceChecker(), collection, nil) - Expect(err).To(BeNil()) - - Expect(rollback.Execute(utils.JellyfishDataQueryFn, utils.JellyfishDataUpdatesFn)).To(Succeed()) - - cur, err = collection.Find(ctx, bson.D{}, findOptions) - Expect(err).To(BeNil()) - rolledback := []map[string]interface{}{} - cur.All(ctx, &rolledback) - Expect(len(rolledback)).To(Equal(datumCount)) + Expect(len(migrated)).To(Equal(uploadCount)) - for i, rollbackItem := range rolledback { - Expect(migrated[i]["_id"]).To(Equal(rollbackItem["_id"])) - Expect(original[i]).To(Equal(rollbackItem)) + for _, item := range migrated { + Expect(item).Should(HaveKey("_deduplicator")) + Expect(item["_deduplicator"]).Should(HaveLen(2)) + Expect(item["_deduplicator"]).Should(HaveKeyWithValue("name", deduplicator.DeviceDeactivateLegacyHashName)) + Expect(item["_deduplicator"]).Should(HaveKeyWithValue("version", "0.0.0")) } - }) }) }) diff --git a/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go b/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go index a42e37a1e6..4529f85e63 100644 --- a/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go +++ b/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go @@ -2,14 +2,13 @@ package utils import ( "errors" - "fmt" "log" "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" + "github.com/tidepool-org/platform/data/deduplicator/deduplicator" "github.com/tidepool-org/platform/pointer" ) @@ -17,11 +16,6 @@ func jellyfishQuery(settings Settings, userID *string, lastFetchedID *string) (b selector := bson.M{ "_deduplicator": bson.M{"$exists": false}, } - if settings.Rollback { - selector = bson.M{ - settings.RollbackSectionName: bson.M{"$exists": true}, - } - } if userID != nil && *userID != "" { log.Printf("fetching for user %s", *userID) @@ -61,6 +55,7 @@ var JellyfishDataQueryFn = func(m *DataMigration) bool { pointer.FromString(m.GetLastID()), ) + opts.Projection = bson.M{"_id": 1} dDataCursor, err := dataC.Find(m.GetCtx(), selector, opts) if err != nil { log.Printf("failed to select data: %s", err) @@ -68,56 +63,28 @@ var JellyfishDataQueryFn = func(m *DataMigration) bool { } defer dDataCursor.Close(m.GetCtx()) - all := []bson.M{} + count := 0 for dDataCursor.Next(m.GetCtx()) { - item := bson.M{} - if err := dDataCursor.Decode(&item); err != nil { - log.Printf("error decoding data: %s", err) - return false + m.UpdateFetchedCount() + var result struct { + ID string `bson:"_id"` } - itemID := fmt.Sprintf("%v", item["_id"]) - userID := fmt.Sprintf("%v", item["_userId"]) - itemType := fmt.Sprintf("%v", item["type"]) - if settings.Rollback { - if rollback, ok := item[settings.RollbackSectionName].(primitive.A); ok { - cmds := []bson.M{} - for _, cmd := range rollback { - if cmd, ok := cmd.(bson.M); ok { - cmds = append(cmds, cmd) - } - } - if len(cmds) > 0 { - m.SetUpdates(UpdateData{ - Filter: bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}, - ItemID: itemID, - UserID: userID, - ItemType: itemType, - Apply: cmds, - }) - } - } - + if err := dDataCursor.Decode(&result); err != nil { + m.OnError(ErrorData{Error: err}) + continue } else { - updates, revert, err := ProcessDatum(itemID, itemType, item) - if err != nil { - m.OnError(ErrorData{Error: err, ItemID: itemID, ItemType: itemType}) - } else if len(updates) > 0 { - m.SetUpdates(UpdateData{ - Filter: bson.M{"_id": itemID, "modifiedTime": item["modifiedTime"]}, - ItemID: itemID, - UserID: userID, - ItemType: itemType, - Apply: updates, - Revert: revert, - }) - } + setDeduplicator := bson.M{"$set": bson.M{"_deduplicator": bson.M{"hash": result.ID}}} + m.SetUpdates(UpdateData{ + Filter: bson.M{"_id": result.ID}, + ItemID: result.ID, + Apply: []bson.M{setDeduplicator}, + }) + count++ + m.SetLastProcessed(result.ID) } - m.SetLastProcessed(itemID) - all = append(all, item) } - m.SetFetched(all) - return len(all) > 0 + return count > 0 } return false } @@ -146,7 +113,6 @@ var JellyfishDataUpdatesFn = func(m *DataMigration) (int, error) { } writtenCount := 0 for _, batch := range getBatches(int(*settings.WriteBatchSize)) { - if err := m.CheckMongoInstance(); err != nil { return writtenCount, err } @@ -163,3 +129,48 @@ var JellyfishDataUpdatesFn = func(m *DataMigration) (int, error) { } return writtenCount, nil } + +var JellyfishUploadQueryFn = func(m *DataMigration) bool { + + settings := m.GetSettings() + + if dataC := m.GetDataCollection(); dataC != nil { + + selector, opts := jellyfishQuery( + settings, + nil, + pointer.FromString(m.GetLastID()), + ) + + opts.Projection = bson.M{"_id": 1} + dDataCursor, err := dataC.Find(m.GetCtx(), selector, opts) + if err != nil { + log.Printf("failed to select upload data: %s", err) + return false + } + defer dDataCursor.Close(m.GetCtx()) + + count := 0 + + for dDataCursor.Next(m.GetCtx()) { + m.UpdateFetchedCount() + var result struct { + ID string `bson:"_id"` + } + if err := dDataCursor.Decode(&result); err != nil { + m.OnError(ErrorData{Error: err}) + continue + } else { + m.SetUpdates(UpdateData{ + Filter: bson.M{"_id": result.ID}, + ItemID: result.ID, + Apply: []bson.M{{"$set": bson.M{"_deduplicator": bson.M{"name": deduplicator.DeviceDeactivateLegacyHashName, "version": "0.0.0"}}}}, + }) + count++ + m.SetLastProcessed(result.ID) + } + } + return count > 0 + } + return false +} diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go index 3a548ecfec..b2cddfe2bc 100644 --- a/migrations/20231128_jellyfish_migration/utils/test/data.go +++ b/migrations/20231128_jellyfish_migration/utils/test/data.go @@ -7,28 +7,10 @@ import ( "strings" "time" - "github.com/tidepool-org/platform/data/types/settings/pump" - pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" "github.com/tidepool-org/platform/test" ) -func base(deviceID string) map[string]interface{} { - return map[string]interface{}{ - "_id": "17dbokav5t6pssjv72gm0nie3u25b54m", - "deviceId": deviceID, - "deviceTime": "2017-11-05T12:56:51", - "id": "3f0075ad57ad603c83dc1e1a76aefcaf", - "_userId": "8da6e693b8", - "_groupId": "87df73fd41", - "createdTime": "2022-06-21T22:40:07.732+00:00", - "_version": 0, - "_active": true, - "uploadId": "a21c82a5f5d2860add2539acded6b614", - "time": "2022-06-21T22:40:07.732+00:00", - } -} - -func baseWithTime(deviceID string, groupID string, userID string, t time.Time) map[string]interface{} { +func datumBase(deviceID string, groupID string, userID string, t time.Time) map[string]interface{} { now := time.Now() return map[string]interface{}{ "_id": "17dbokav5t6pssjv72gm0nie3u25b54m", @@ -54,215 +36,6 @@ func dexG5MobDatumStringPayload(datum map[string]interface{}) map[string]interfa return datum } -func dexG5MobDatumStringAnnotations(datum map[string]interface{}) map[string]interface{} { - datum["annotations"] = `[{"code":"bg/out-of-range","threshold":40,"value":"low"}]` - datum["type"] = "cbg" - datum["units"] = "mmol/L" - datum["value"] = 8.1596 - return datum -} - -func tandemPumpSettingsDatum(datum map[string]interface{}) map[string]interface{} { - datum["type"] = "pumpSettings" - datum["activeSchedule"] = "Simple" - datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mmol/l"} - datum["basalSchedules"] = map[string]interface{}{ - "Simple": []map[string]interface{}{ - {"rate": 0.5, "start": 0}, - {"rate": 1.35, "start": 55800000}, - }, - "Standard": []map[string]interface{}{ - {"rate": 0.5, "start": 0}, - {"rate": 1.35, "start": 55800000}, - }, - } - datum["carbRatios"] = map[string]interface{}{ - "Simple": []map[string]interface{}{ - {"amount": 10, "start": 0}, - {"amount": 10, "start": 46800000}, - }, - "Standard": []map[string]interface{}{ - {"amount": 10, "start": 0}, - {"amount": 10, "start": 46800000}, - }, - } - datum["insulinSensitivities"] = map[string]interface{}{ - "Simple": []map[string]interface{}{ - {"amount": 2.7753739955227665, "start": 0}, - {"amount": 2.7753739955227665, "start": 46800000}, - }, - "Standard": []map[string]interface{}{ - {"amount": 2.7753739955227665, "start": 0}, - {"amount": 2.7753739955227665, "start": 46800000}, - }, - } - - datum["payload"] = map[string]interface{}{ - "logIndices": []interface{}{0}, - } - - return datum -} - -func tandemPumpSettingsWithSleepScheduleDatum(datum map[string]interface{}) map[string]interface{} { - datum["type"] = "pumpSettings" - datum["activeSchedule"] = "Simple" - datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mmol/L"} - datum["basalSchedules"] = map[string]interface{}{ - "Simple": []map[string]interface{}{ - {"rate": 0.5, "start": 0}, - {"rate": 1.35, "start": 55800000}, - }, - "Standard": []map[string]interface{}{ - {"rate": 0.5, "start": 0}, - {"rate": 1.35, "start": 55800000}, - }, - } - datum["carbRatios"] = map[string]interface{}{ - "Simple": []map[string]interface{}{ - {"amount": 10, "start": 0}, - {"amount": 10, "start": 46800000}, - }, - "Standard": []map[string]interface{}{ - {"amount": 10, "start": 0}, - {"amount": 10, "start": 46800000}, - }, - } - datum["insulinSensitivities"] = map[string]interface{}{ - "Simple": []map[string]interface{}{ - {"amount": 2.7753739955227665, "start": 0}, - {"amount": 2.7753739955227665, "start": 46800000}, - }, - "Standard": []map[string]interface{}{ - {"amount": 2.7753739955227665, "start": 0}, - {"amount": 2.7753739955227665, "start": 46800000}, - }, - } - - datum["bgTargets"] = map[string]interface{}{ - "Simple": []map[string]interface{}{ - {"target": 5.550747991045533, "start": 0}, - {"target": 5.550747991045533, "start": 46800000}, - }, - "Standard": []map[string]interface{}{ - {"target": 5.550747991045533, "start": 0}, - {"target": 5.550747991045533, "start": 46800000}, - }, - } - - datum["payload"] = map[string]interface{}{ - "logIndices": []interface{}{0}, - } - - datum["sleepSchedules"] = []interface{}{ - map[string]interface{}{"days": []interface{}{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}, "enabled": true, "end": 25200, "start": 82800}, - map[string]interface{}{"days": []interface{}{"Sunday"}, "enabled": false, "end": 32400, "start": 3600}, - } - - return datum -} - -func carelinkPumpSettings(datum map[string]interface{}) map[string]interface{} { - datum["type"] = "pumpSettings" - datum["activeSchedule"] = "standard" - datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mmol/L"} - datum["basalSchedules"] = map[string]interface{}{ - "standard": []map[string]interface{}{ - {"rate": 0.5, "start": 0}, - {"rate": 1.35, "start": 55800000}, - }, - "pattern a": []map[string]interface{}{ - {"rate": 0.5, "start": 0}, - {"rate": 1.35, "start": 55800000}, - }, - "pattern b": []map[string]interface{}{}, - } - datum["carbRatio"] = []map[string]interface{}{ - {"amount": 10, "start": 0}, - {"amount": 10, "start": 32400000}, - } - datum["insulinSensitivity"] = []map[string]interface{}{ - {"amount": 2.7753739955227665, "start": 0}, - {"amount": 2.7753739955227665, "start": 46800000}, - } - - datum["bgTarget"] = []map[string]interface{}{ - {"target": 5.550747991045533, "start": 0}, - {"target": 5.550747991045533, "start": 46800000}, - } - - datum["payload"] = map[string]interface{}{ - "logIndices": []interface{}{5309}, - } - return datum -} - -func omnipodPumpSettingsDatum(datum map[string]interface{}) map[string]interface{} { - datum["type"] = "pumpSettings" - datum["activeSchedule"] = "Mine-2016" - datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mg/dL"} - datum["basalSchedules"] = map[string]interface{}{ - "Mine-2016": []map[string]interface{}{ - {"rate": 0.5, "start": 0}, - {"rate": 1.35, "start": 55800000}, - }, - "camp 2015": []map[string]interface{}{ - {"rate": 0.5, "start": 0}, - {"rate": 1.35, "start": 55800000}, - }, - "weekend b": []map[string]interface{}{}, - } - datum["carbRatio"] = []map[string]interface{}{ - {"amount": 10, "start": 0}, - {"amount": 10, "start": 32400000}, - } - datum["insulinSensitivity"] = []map[string]interface{}{ - {"amount": 2.7753739955227665, "start": 0}, - {"amount": 2.7753739955227665, "start": 46800000}, - } - - datum["bgTarget"] = []map[string]interface{}{ - {"target": 5.550747991045533, "start": 0, "high": 7.2159723883591935}, - {"target": 5.550747991045533, "start": 46800000, "high": 7.2159723883591935}, - } - return datum -} - -func pumpSettingsWithTargetsDatum(datum map[string]interface{}) map[string]interface{} { - datum["type"] = "pumpSettings" - datum["activeSchedule"] = "test" - datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mmol/L"} - datum["basalSchedules"] = map[string]interface{}{ - "test": []map[string]interface{}{ - {"rate": 0.5, "start": 0}, - {"rate": 1.35, "start": 55800000}, - }, - "weekend b": []map[string]interface{}{}, - } - datum["carbRatio"] = []map[string]interface{}{ - {"amount": 10, "start": 0}, - {"amount": 10, "start": 32400000}, - } - datum["insulinSensitivity"] = []map[string]interface{}{ - {"amount": 2.7753739955227665, "start": 0}, - {"amount": 2.7753739955227665, "start": 46800000}, - } - - datum["bgTarget"] = []map[string]interface{}{ - {"target": 5.550747991045533, "start": 0, "high": 7.2159723883591935}, - } - - datum["bgTargetPhysicalActivity"] = map[string]interface{}{ - "low": 2.7753739955227665, "high": 7.2159723883591935, - } - - datum["bgTargetPreprandial"] = map[string]interface{}{ - "low": 2.7753739955227665, "high": 7.2159723883591935, - } - - return datum -} - func omnipodPumpSettingsDatumTargetSet(datum map[string]interface{}) map[string]interface{} { datum["type"] = "pumpSettings" datum["activeSchedule"] = "Mine-2016" @@ -294,24 +67,6 @@ func omnipodPumpSettingsDatumTargetSet(datum map[string]interface{}) map[string] return datum } -func tandemAutomatedBasalDatum(datum map[string]interface{}) map[string]interface{} { - datum["type"] = "basal" - datum["deliveryType"] = "automated" - datum["timezoneOffset"] = -300 - datum["clockDriftOffset"] = -137000 - datum["conversionOffset"] = 0 - datum["duration"] = 300000 - datum["rate"] = 0.335 - datum["percent"] = 0.47857142857142865 - datum["conversionOffset"] = 0 - datum["suppressed"] = map[string]interface{}{ - "type": "basal", - "deliveryType": "scheduled", - "rate": 0.7, - } - return datum -} - func tandemWizardDatum(datum map[string]interface{}) map[string]interface{} { datum["type"] = "wizard" @@ -340,13 +95,6 @@ func tandemWizardDatum(datum map[string]interface{}) map[string]interface{} { return datum } -func reservoirChangeDeviceEventDatum(datum map[string]interface{}) map[string]interface{} { - datum["type"] = "deviceEvent" - datum["subType"] = "reservoirChange" - datum["status"] = "cvv61jde62b6i28bgot57f18bor5au1n" - return datum -} - func alarmDeviceEventDatum(datum map[string]interface{}) map[string]interface{} { datum["type"] = "deviceEvent" datum["subType"] = "status" @@ -392,97 +140,26 @@ func cgmSettingsDatum(datum map[string]interface{}) map[string]interface{} { return datum } -func emptyPayload(datum map[string]interface{}) map[string]interface{} { - datum["payload"] = map[string]interface{}{} - datum["type"] = "cbg" - datum["units"] = "mmol/L" - datum["value"] = 8.1596 - return datum -} - -func extraFields(datum map[string]interface{}) map[string]interface{} { - datum["payload"] = map[string]interface{}{} - datum["type"] = "cbg" - datum["units"] = "mmol/L" - datum["value"] = 8.1596 - datum["index"] = 0 - datum["localTime"] = "2017-11-05T12:56:51.000Z" - datum["jsDate"] = "2017-11-05T12:56:51.000Z" - return datum -} - -func pumpSettingsWithBolus(datum map[string]interface{}) map[string]interface{} { - datum = tandemPumpSettingsDatum(datum) - datum["bolus"] = &pump.BolusMap{ - "bolus-1": pumpTest.NewRandomBolus(), - "bolus-2": pumpTest.NewRandomBolus(), +var makeJellyfishID = func(fields []string) string { + h := sha1.New() + hashFields := append(fields, "bootstrap") + for _, field := range hashFields { + io.WriteString(h, field) + io.WriteString(h, "_") } - return datum -} - -// payload as a string rather than object or array -func cbgDatum(datum map[string]interface{}) map[string]interface{} { - datum["type"] = "cbg" - datum["units"] = "mmol/L" - datum["value"] = 3.8855235937318735 - return datum -} - -func smbgDatum(datum map[string]interface{}) map[string]interface{} { - datum["type"] = "smbg" - datum["units"] = "mmol/L" - datum["value"] = 22.202991964182132 - return datum + sha1 := h.Sum(nil) + id := strings.ToLower(base32.HexEncoding.WithPadding('-').EncodeToString(sha1)) + return id } -func bloodKetoneDatum(datum map[string]interface{}) map[string]interface{} { - datum["type"] = "bloodKetone" - datum["units"] = "mmol/L" - datum["value"] = 7.2159723883591935 - return datum -} - -var CBGDexcomG5StringPayloadDatum = dexG5MobDatumStringPayload(base("DexG5Mob_iPhone")) -var CBGDexcomG5StringAnnotationsDatum = dexG5MobDatumStringAnnotations(base("DexG5Mob_iPhone")) -var PumpSettingsTandem = tandemPumpSettingsDatum(base("tandem99999999")) -var PumpSettingsWithSleepScheduleTandem = tandemPumpSettingsWithSleepScheduleDatum(base("tandem99999999")) -var PumpSettingsCarelink = carelinkPumpSettings(base("MiniMed 530G - 751-=-11111111")) -var PumpSettingsOmnipod = omnipodPumpSettingsDatum(base("InsOmn-837268")) -var PumpSettingsOmnipodBGTargetCorrect = omnipodPumpSettingsDatumTargetSet(base("InsOmn-837268")) -var AutomatedBasalTandem = tandemAutomatedBasalDatum(base("tandemCIQ1111111111111")) -var WizardTandem = tandemWizardDatum(base("tandemCIQ1111111111111")) -var ReservoirChangeWithStatus = reservoirChangeDeviceEventDatum(base("InsOmn-1111111111111")) -var AlarmDeviceEventDatum = alarmDeviceEventDatum(base("tandemCIQ100000000000")) -var CGMSetting = cgmSettingsDatum(base("DexG5MobRec-1111111111111")) -var EmptyPayloadDatum = emptyPayload(base("Dex-device")) -var ExtraFieldsDatum = extraFields(base("my-device")) -var PumpSettingsWithBolusDatum = pumpSettingsWithBolus(base("tandem99999999")) -var PumpSettingsWithTarget = pumpSettingsWithTargetsDatum(base("my-pump-123")) - -var SMBGValueDatum = smbgDatum(base("smbg-device-123")) -var CBGValueDatum = cbgDatum(base("cbg-device-987")) -var BloodKetoneValueDatum = bloodKetoneDatum(base("blood-ketone-device-456")) - func BulkJellyfishData(deviceID string, groupID string, userID string, requiredRecords int) []map[string]interface{} { data := []map[string]interface{}{} twoWeeksAgo := time.Now().AddDate(0, 0, 14) - var makeJellyfishID = func(fields []string) string { - h := sha1.New() - hashFields := append(fields, "bootstrap") - for _, field := range hashFields { - io.WriteString(h, field) - io.WriteString(h, "_") - } - sha1 := h.Sum(nil) - id := strings.ToLower(base32.HexEncoding.WithPadding('-').EncodeToString(sha1)) - return id - } - for count := 0; count < requiredRecords; count++ { typ := test.RandomChoice([]string{"cbg", "wizard", "deviceEvent"}) dTime := twoWeeksAgo.Add(time.Duration(count) * time.Minute) - base := baseWithTime(deviceID, groupID, userID, dTime) + base := datumBase(deviceID, groupID, userID, dTime) var datum map[string]interface{} switch typ { @@ -503,3 +180,32 @@ func BulkJellyfishData(deviceID string, groupID string, userID string, requiredR } return data } + +func uploadDatum(datum map[string]interface{}, t time.Time) map[string]interface{} { + datum["type"] = "upload" + datum["computerTime"] = t.Format("2006-01-02T15:04:05") + datum["deviceTags"] = []string{ + "cgm", + "insulin-pump", + } + datum["deviceManufacturers"] = []string{ + "Medtronic", + } + datum["deviceModel"] = "MiniMed 530G 551" + datum["timeProcessing"] = "utc-bootstrapping" + return datum +} + +func BulkJellyfishUploadData(deviceID string, groupID string, userID string, requiredRecords int) []map[string]interface{} { + data := []map[string]interface{}{} + twoMonthsAgo := time.Now().AddDate(0, 2, 00) + for count := 0; count < requiredRecords; count++ { + typ := test.RandomChoice([]string{"cbg", "wizard", "deviceEvent"}) + dTime := twoMonthsAgo.Add(time.Duration(count) * time.Hour) + datum := uploadDatum(datumBase(deviceID, groupID, userID, dTime), dTime) + datum["_id"] = makeJellyfishID([]string{userID, deviceID, dTime.Format(time.RFC3339), typ}) + datum["id"] = datum["_id"] + data = append(data, datum) + } + return data +} diff --git a/migrations/20231128_jellyfish_migration/utils/utils.go b/migrations/20231128_jellyfish_migration/utils/utils.go deleted file mode 100644 index eb77e51d14..0000000000 --- a/migrations/20231128_jellyfish_migration/utils/utils.go +++ /dev/null @@ -1,472 +0,0 @@ -package utils - -import ( - "encoding/json" - "fmt" - "log" - "slices" - "strings" - "time" - - "github.com/r3labs/diff/v3" - "go.mongodb.org/mongo-driver/bson" - - "github.com/tidepool-org/platform/data" - "github.com/tidepool-org/platform/data/blood/glucose" - "github.com/tidepool-org/platform/data/deduplicator/deduplicator" - dataNormalizer "github.com/tidepool-org/platform/data/normalizer" - "github.com/tidepool-org/platform/data/types/basal" - "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" - "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" - "github.com/tidepool-org/platform/data/types/blood/ketone" - "github.com/tidepool-org/platform/data/types/bolus" - "github.com/tidepool-org/platform/data/types/calculator" - "github.com/tidepool-org/platform/data/types/common" - "github.com/tidepool-org/platform/data/types/device" - "github.com/tidepool-org/platform/data/types/device/alarm" - "github.com/tidepool-org/platform/data/types/device/reservoirchange" - dataTypesFactory "github.com/tidepool-org/platform/data/types/factory" - "github.com/tidepool-org/platform/data/types/settings/cgm" - "github.com/tidepool-org/platform/data/types/settings/pump" - errorsP "github.com/tidepool-org/platform/errors" - "github.com/tidepool-org/platform/pointer" - structureParser "github.com/tidepool-org/platform/structure/parser" - structureValidator "github.com/tidepool-org/platform/structure/validator" -) - -// NOTE: required to ensure consitent precision of bg values in the platform -func getBGValuePrecision(val float64) float64 { - floatStr := fmt.Sprintf("%v", val) - if _, floatParts, found := strings.Cut(floatStr, "."); found { - if len(floatParts) > 5 { - mgdlVal := val * glucose.MmolLToMgdLConversionFactor - intValue := int(mgdlVal/glucose.MmolLToMgdLConversionFactor*glucose.MmolLToMgdLPrecisionFactor + 0.5) - floatValue := float64(intValue) / glucose.MmolLToMgdLPrecisionFactor - return floatValue - } - } - return val -} - -func deepCopy(src map[string]interface{}, dest map[string]interface{}) error { - jsonStr, err := json.Marshal(src) - if err != nil { - return err - } - err = json.Unmarshal(jsonStr, &dest) - if err != nil { - return err - } - return nil -} - -func updateTargets(targets interface{}) { - if targetObjs, ok := targets.([]interface{}); ok { - for i, target := range targetObjs { - if targetObj, ok := target.(map[string]interface{}); ok { - targetObjs[i] = updateTragetPrecision(targetObj) - } - } - } -} - -func updateTragetPrecision(targetObj map[string]interface{}) map[string]interface{} { - if targetObj["high"] != nil { - if highVal, ok := targetObj["high"].(float64); ok { - targetObj["high"] = getBGValuePrecision(highVal) - } - } - if targetObj["low"] != nil { - if lowVal, ok := targetObj["low"].(float64); ok { - targetObj["low"] = getBGValuePrecision(lowVal) - } - } - if targetObj["range"] != nil { - if rangeVal, ok := targetObj["range"].(float64); ok { - targetObj["range"] = getBGValuePrecision(rangeVal) - } - } - if targetObj["target"] != nil { - if targetVal, ok := targetObj["target"].(float64); ok { - targetObj["target"] = getBGValuePrecision(targetVal) - } - } - return targetObj -} - -func (b *builder) applyBaseUpdates(incomingObject map[string]interface{}) (map[string]interface{}, error) { - updatedObject := map[string]interface{}{} - err := deepCopy(incomingObject, updatedObject) - if err != nil { - return nil, err - } - switch b.datumType { - case pump.Type: - - if units, ok := updatedObject["units"].(map[string]interface{}); ok { - units["bg"] = glucose.MmolL - } - - if boluses := updatedObject["bolus"]; boluses != nil { - // NOTE: fix mis-named boluses which were saved in jellyfish as a `bolus` - updatedObject["boluses"] = boluses - delete(updatedObject, "bolus") - } - if schedules := updatedObject["sleepSchedules"]; schedules != nil { - // NOTE: this is to fix sleepSchedules so they are in the required map format - scheduleNames := map[int]string{0: "1", 1: "2"} - sleepScheduleMap := map[string]interface{}{} - dataBytes, err := json.Marshal(schedules) - if err != nil { - return nil, err - } - schedulesArray := []map[string]interface{}{} - err = json.Unmarshal(dataBytes, &schedulesArray) - if err != nil { - return nil, err - } - for i, schedule := range schedulesArray { - days := schedule["days"].([]interface{}) - updatedDays := []string{} - for _, day := range days { - if !slices.Contains(common.DaysOfWeek(), strings.ToLower(fmt.Sprintf("%v", day))) { - return nil, errorsP.Newf("pumpSettings.sleepSchedules has an invalid day of week %s", day) - } - updatedDays = append(updatedDays, strings.ToLower(fmt.Sprintf("%v", day))) - } - schedule["days"] = updatedDays - sleepScheduleMap[scheduleNames[i]] = schedule - } - updatedObject["sleepSchedules"] = sleepScheduleMap - } - if bgTargetPhysicalActivity := updatedObject["bgTargetPhysicalActivity"]; bgTargetPhysicalActivity != nil { - if targetObj, ok := bgTargetPhysicalActivity.(map[string]interface{}); ok { - updatedObject["bgTargetPhysicalActivity"] = updateTragetPrecision(targetObj) - } - } - if bgTargetPreprandial := updatedObject["bgTargetPreprandial"]; bgTargetPreprandial != nil { - if targetObj, ok := bgTargetPreprandial.(map[string]interface{}); ok { - updatedObject["bgTargetPreprandial"] = updateTragetPrecision(targetObj) - } - } - if bgTarget := updatedObject["bgTarget"]; bgTarget != nil { - updateTargets(bgTarget) - } - if bgTargets := updatedObject["bgTargets"]; bgTargets != nil { - if targetMaps, ok := bgTargets.(map[string]interface{}); ok { - for _, targets := range targetMaps { - updateTargets(targets) - } - } - } - if overridePresets := updatedObject["overridePresets"]; overridePresets != nil { - log.Printf("## TODO [%s] [%s] overridePresets", b.datumType, b.datumID) - } - - case selfmonitored.Type, ketone.Type, continuous.Type: - units := fmt.Sprintf("%v", updatedObject["units"]) - if units == glucose.MmolL || units == glucose.Mmoll { - if bgVal, ok := updatedObject["value"].(float64); ok { - updatedObject["value"] = getBGValuePrecision(bgVal) - } - } - case cgm.Type: - units := fmt.Sprintf("%v", updatedObject["units"]) - if units == glucose.MmolL || units == glucose.Mmoll { - if lowAlerts, ok := updatedObject["lowAlerts"].(map[string]interface{}); ok { - if bgVal, ok := lowAlerts["level"].(float64); ok { - lowAlerts["level"] = getBGValuePrecision(bgVal) - updatedObject["lowAlerts"] = lowAlerts - } - } - if highAlerts, ok := updatedObject["highAlerts"].(map[string]interface{}); ok { - if bgVal, ok := highAlerts["level"].(float64); ok { - highAlerts["level"] = getBGValuePrecision(bgVal) - updatedObject["highAlerts"] = highAlerts - } - } - } - case calculator.Type: - - if units := fmt.Sprintf("%v", updatedObject["units"]); units != glucose.MmolL { - updatedObject["units"] = glucose.MmolL - } - - if bolus := updatedObject["bolus"]; bolus != nil { - // NOTE: we are doing this to ensure that the `bolus` is a valid id reference - if bolusID, ok := bolus.(string); ok { - delete(updatedObject, "bolus") - updatedObject["bolusId"] = bolusID - } - } - if bgTargetObj, ok := updatedObject["bgTarget"].(map[string]interface{}); ok { - updatedObject["bgTarget"] = updateTragetPrecision(bgTargetObj) - } - if bgInput, ok := updatedObject["bgInput"].(float64); ok { - updatedObject["bgInput"] = getBGValuePrecision(bgInput) - } - case device.Type: - subType := fmt.Sprintf("%v", updatedObject["subType"]) - switch subType { - case reservoirchange.SubType, alarm.SubType: - // NOTE: we are doing this to ensure that the `status` is just a string reference and then setting the `statusId` with it - if status := updatedObject["status"]; status != nil { - if statusID, ok := status.(string); ok { - updatedObject["statusId"] = statusID - delete(updatedObject, "status") - } - } - } - } - - if payload := updatedObject["payload"]; payload != nil { - - if m, ok := payload.(map[string]interface{}); ok { - if length := len(m); length == 0 { - delete(updatedObject, "payload") - } - } - if strPayload, ok := payload.(string); ok { - var payloadMetadata map[string]interface{} - err := json.Unmarshal(json.RawMessage(strPayload), &payloadMetadata) - if err != nil { - return nil, errorsP.Newf("payload could not be set from %s", strPayload) - } - updatedObject["payload"] = payloadMetadata - } - - } - if annotations := updatedObject["annotations"]; annotations != nil { - if strAnnotations, ok := annotations.(string); ok { - var metadataArray []interface{} - if err := json.Unmarshal(json.RawMessage(strAnnotations), &metadataArray); err != nil { - return nil, errorsP.Newf("annotations could not be set from %s", strAnnotations) - } - updatedObject["annotations"] = metadataArray - } - } - return updatedObject, nil -} - -func (b *builder) buildDatum(obj map[string]interface{}) error { - parser := structureParser.NewObject(&obj) - validator := structureValidator.New() - normalizer := dataNormalizer.New() - - datum := dataTypesFactory.ParseDatum(parser) - if datum != nil && *datum != nil { - (*datum).SetUserID(parser.String("_userId")) - (*datum).SetCreatedTime(parser.Time("createdTime", time.RFC3339Nano)) - (*datum).Validate(validator) - (*datum).Normalize(normalizer) - } else { - return errorsP.Newf("no datum returned for id=[%s]", b.datumID) - } - - validator.Bool("_active", parser.Bool("_active")).Exists() - validator.String("_archivedTime", parser.String("_archivedTime")) - validator.String("_groupId", parser.String("_groupId")).Exists() - validator.String("_id", parser.String("_id")).Exists() - validator.Int("_version", parser.Int("_version")).Exists() - validator.Int("_schemaVersion", parser.Int("_schemaVersion")) - validator.Object("_deduplicator", parser.Object("_deduplicator")) - - validator.String("uploadId", parser.String("uploadId")).Exists() - validator.String("guid", parser.String("guid")) - validator.Time("modifiedTime", parser.Time("modifiedTime", time.RFC3339Nano)) - validator.Time("localTime", parser.Time("localTime", time.RFC3339Nano)) - - //parsed but not used in the platform - //deletes will be created from the diff - - switch b.datumType { - case continuous.Type: - validator.String("subType", parser.String("subType")) - validator.String("jsDate", parser.String("jsDate")) - validator.Int("index", parser.Int("index")) - case bolus.Type: - validator.String("deliveryContext", parser.String("deliveryContext")) - case basal.Type: - validator.Object("suppressed", parser.Object("suppressed")) - validator.Float64("percent", parser.Float64("percent")) - validator.Float64("rate", parser.Float64("rate")) - case device.Type: - validator.Object("previous", parser.Object("previous")) - validator.String("previousOverride", parser.String("previousOverride")) - validator.Int("index", parser.Int("index")) - validator.String("statusId", parser.String("statusId")) - case calculator.Type: - validator.Float64("percent", parser.Float64("percent")) - validator.Float64("rate", parser.Float64("rate")) - validator.Int("duration", parser.Int("duration")) - validator.String("bolusId", parser.String("bolusId")) - } - - parser.NotParsed() - - if err := parser.Error(); err != nil { - return err - } - - if err := validator.Error(); err != nil { - return err - } - - if err := normalizer.Error(); err != nil { - return err - } - - fields, err := (*datum).IdentityFields() - if err != nil { - return errorsP.Wrap(err, "unable to gather identity fields for datum") - } - - hash, err := deduplicator.GenerateIdentityHash(fields) - if err != nil { - return errorsP.Wrap(err, "unable to generate identity hash for datum") - } - - deduplicator := (*datum).DeduplicatorDescriptor() - if deduplicator == nil { - deduplicator = data.NewDeduplicatorDescriptor() - } - deduplicator.Hash = pointer.FromString(hash) - - (*datum).SetDeduplicatorDescriptor(deduplicator) - - b.datum = *datum - return nil -} - -func (b *builder) datumChanges(storedObj map[string]interface{}) ([]bson.M, []bson.M, error) { - - datumJSON, err := json.Marshal(b.datum) - if err != nil { - return nil, nil, err - } - - datumObject := map[string]interface{}{} - if err := json.Unmarshal(datumJSON, &datumObject); err != nil { - return nil, nil, err - } - - if b.datumType == calculator.Type { - //we have validated the id but don't want to trigger an update - delete(storedObj, "bolus") - } - if b.datumType == device.Type { - //we have validated the id but don't want to trigger an update - subType := fmt.Sprintf("%v", storedObj["subType"]) - switch subType { - case reservoirchange.SubType, alarm.SubType: - delete(storedObj, "status") - } - } - - if deduplicator := datumObject["deduplicator"]; deduplicator != nil { - datumObject["_deduplicator"] = deduplicator - } - - // these are extras that we want to leave on the - // original object so don't compare - notRequired := []string{ - "_active", - "_archivedTime", - "_groupId", - "_id", - "_schemaVersion", - "_userId", - "_version", - "createdTime", - "guid", - "modifiedTime", - "uploadId", - "deduplicator", - "time", - } - - for _, key := range notRequired { - delete(storedObj, key) - delete(datumObject, key) - } - - changelog, err := diff.Diff(storedObj, datumObject, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true)) - if err != nil { - return nil, nil, err - } - - applySet := bson.M{} - revertSet := bson.M{} - applyUnset := bson.M{} - revertUnset := bson.M{} - - for _, change := range changelog { - switch change.Type { - case diff.CREATE: - applySet[strings.Join(change.Path, ".")] = change.To - revertUnset[strings.Join(change.Path, ".")] = "" - case diff.UPDATE: - applySet[strings.Join(change.Path, ".")] = change.To - revertSet[strings.Join(change.Path, ".")] = change.From - case diff.DELETE: - applyUnset[strings.Join(change.Path, ".")] = "" - revertSet[strings.Join(change.Path, ".")] = change.From - } - } - - apply := []bson.M{} - revert := []bson.M{} - if len(applySet) > 0 { - apply = append(apply, bson.M{"$set": applySet}) - } - if len(revertUnset) > 0 { - revert = append(revert, bson.M{"$unset": revertUnset}) - } - if len(applyUnset) > 0 { - apply = append(apply, bson.M{"$unset": applyUnset}) - } - if len(revertSet) > 0 { - revert = append(revert, bson.M{"$set": revertSet}) - } - return apply, revert, nil -} - -type builder struct { - datumType string - datumID string - datum data.Datum -} - -func ProcessDatum(dataID string, dataType string, bsonData bson.M) ([]bson.M, []bson.M, error) { - - b := &builder{ - datumType: dataType, - datumID: dataID, - } - - storedJSON, err := json.Marshal(bsonData) - if err != nil { - return nil, nil, err - } - - storedData := map[string]interface{}{} - if err := json.Unmarshal(storedJSON, &storedData); err != nil { - return nil, nil, err - } - - updatedData, err := b.applyBaseUpdates(storedData) - if err != nil { - return nil, nil, err - } - - if err := b.buildDatum(updatedData); err != nil { - return nil, nil, err - } - - apply, revert, err := b.datumChanges(storedData) - - if err != nil { - return nil, nil, err - } - return apply, revert, nil -} diff --git a/migrations/20231128_jellyfish_migration/utils/utils_test.go b/migrations/20231128_jellyfish_migration/utils/utils_test.go deleted file mode 100644 index 542af171f9..0000000000 --- a/migrations/20231128_jellyfish_migration/utils/utils_test.go +++ /dev/null @@ -1,455 +0,0 @@ -package utils_test - -import ( - "fmt" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/bson/primitive" - - "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" - "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils/test" -) - -var _ = Describe("back-37", func() { - var _ = Describe("utils", func() { - var getBSONData = func(datum interface{}) bson.M { - var bsonData bson.M - bsonAsByte, _ := bson.Marshal(&datum) - bson.Unmarshal(bsonAsByte, &bsonData) - return bsonData - } - - var setup = func(bsonObj bson.M) (applySet interface{}, applyUnset interface{}, revertUnset interface{}, revertSet interface{}) { - datumType := fmt.Sprintf("%v", bsonObj["type"]) - datumID := fmt.Sprintf("%v", bsonObj["_id"]) - apply, revert, err := utils.ProcessDatum(datumID, datumType, bsonObj) - Expect(err).To(BeNil()) - Expect(apply).ToNot(BeNil()) - Expect(revert).ToNot(BeNil()) - - if apply[0] != nil && apply[0]["$set"] != nil { - applySet = apply[0]["$set"] - } - if len(apply) == 2 { - if apply[1]["$unset"] != nil { - applyUnset = apply[1]["$unset"] - } - } - if revert[0] != nil && revert[0]["$unset"] != nil { - revertUnset = revert[0]["$unset"] - } - if len(revert) == 2 { - if revert[1]["$set"] != nil { - revertSet = revert[1]["$set"] - } - } - return applySet, applyUnset, revertUnset, revertSet - } - - var _ = Describe("ProcessDatum", func() { - - It("smbg only sets or reverts _deduplicator and value", func() { - - applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.SMBGValueDatum)) - - Expect(applySet).Should(HaveLen(2)) - Expect(revertUnset).Should(HaveLen(1)) - Expect(applyUnset).Should(BeNil()) - Expect(revertSet).Should(HaveLen(1)) - - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "Q3DdX+M2N0kmtylZBiObYDt7JoFzWNkLWJaYcXXd9Zw="})) - Expect(applySet).Should(HaveKeyWithValue("value", 22.20299)) - Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - Expect(revertSet).Should(HaveKeyWithValue("value", 22.202991964182132)) - - }) - - It("cbg only sets or reverts _deduplicator and value", func() { - - applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.CBGValueDatum)) - - Expect(applySet).Should(HaveLen(2)) - Expect(revertUnset).Should(HaveLen(1)) - Expect(applyUnset).Should(BeNil()) - Expect(revertSet).Should(HaveLen(1)) - - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "kDdzWxsC4qNdfnnuWDYDX+fkZtFF7ZI/ZvvBL5PDa+s="})) - Expect(applySet).Should(HaveKeyWithValue("value", 3.88552)) - Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - Expect(revertSet).Should(HaveKeyWithValue("value", 3.8855235937318735)) - - }) - - It("bloodKetone only sets or reverts _deduplicator and value", func() { - - applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.BloodKetoneValueDatum)) - - Expect(applySet).Should(HaveLen(2)) - Expect(applyUnset).Should(BeNil()) - Expect(revertUnset).Should(HaveLen(1)) - Expect(revertSet).Should(HaveLen(1)) - - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "nkLnx6jBepJGYnBs3xOKCT8wFP5jYTqzi5Dq2NXXy+A="})) - Expect(applySet).Should(HaveKeyWithValue("value", 7.21597)) - Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - Expect(revertSet).Should(HaveKeyWithValue("value", 7.2159723883591935)) - - }) - - It("basal only sets or reverts _deduplicator", func() { - - applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.AutomatedBasalTandem)) - - Expect(applySet).Should(HaveLen(1)) - Expect(applyUnset).Should(HaveLen(1)) - Expect(revertUnset).Should(HaveLen(1)) - Expect(revertSet).Should(HaveLen(1)) - - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "YOItOWBgIIoEkqVsBq9yrOZ5utmsKTIezszpGBj5Vpc="})) - Expect(applyUnset).Should(HaveKeyWithValue("percent", "")) - Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - Expect(revertSet).Should(HaveKeyWithValue("percent", 0.47857142857142865)) - - }) - - Describe("cgmSettings datum", func() { - It("will make _deduplicator, lowAlerts and highAlerts and rateOfChangeAlert updates", func() { - applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.CGMSetting)) - - Expect(applySet).Should(HaveLen(4)) - Expect(applyUnset).Should(HaveLen(1)) - Expect(revertUnset).Should(HaveLen(2)) - Expect(revertSet).Should(HaveLen(3)) - - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "gyyB8OqbErdW2aOOo8POTXk1SNJmu5gDEIaCugTVn3M="})) - Expect(applySet).Should(HaveKeyWithValue("lowAlerts.level", 3.88552)) - Expect(applySet).Should(HaveKeyWithValue("highAlerts.level", 22.20299)) - Expect(applySet).Should(HaveKeyWithValue( - "rateOfChangeAlert", map[string]interface{}{ - "fallRate": map[string]interface{}{ - "enabled": false, - "rate": float64(-0.16652243973136602), - }, - "riseRate": map[string]interface{}{ - "enabled": false, - "rate": float64(0.16652243973136602), - }, - }, - )) - Expect(applyUnset).Should(HaveKeyWithValue("rateOfChangeAlerts", "")) - Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - Expect(revertUnset).Should(HaveKeyWithValue("rateOfChangeAlert", "")) - Expect(revertSet).Should(HaveKeyWithValue("lowAlerts.level", 3.8855235937318735)) - Expect(revertSet).Should(HaveKeyWithValue("highAlerts.level", 22.202991964182132)) - Expect(revertSet).Should(HaveKeyWithValue("rateOfChangeAlerts", map[string]interface{}{ - "fallRate": map[string]interface{}{ - "enabled": false, - "rate": float64(-0.16652243973136602), - }, - "riseRate": map[string]interface{}{ - "enabled": false, - "rate": float64(0.16652243973136602), - }, - })) - }) - }) - Describe("pumpSettings datum", func() { - - It("will make _deduplicator, and bg precision updates ", func() { - applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.PumpSettingsTandem)) - - Expect(applySet).Should(HaveLen(2)) - Expect(revertUnset).Should(HaveLen(1)) - Expect(applyUnset).Should(BeNil()) - Expect(revertSet).Should(HaveLen(1)) - - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "l5e6HoVqMu3ZOUjqaky/m6ZNw+D0UFxbYw/fM9P4PXc="})) - Expect(applySet).Should(HaveKeyWithValue("units.bg", "mmol/L")) - Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - Expect(revertSet).Should(HaveKeyWithValue("units.bg", "mmol/l")) - }) - - It("will make _deduplicator and sleepSchedules updates", func() { - - applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.PumpSettingsWithSleepScheduleTandem)) - - Expect(applySet).Should(HaveLen(6)) - Expect(applyUnset).Should(BeNil()) - Expect(revertUnset).Should(HaveLen(1)) - Expect(revertSet).Should(HaveLen(5)) - - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "l5e6HoVqMu3ZOUjqaky/m6ZNw+D0UFxbYw/fM9P4PXc="})) - - Expect(applySet).Should(HaveKeyWithValue("bgTargets.Simple.0.target", 5.55075)) - Expect(applySet).Should(HaveKeyWithValue("bgTargets.Simple.1.target", 5.55075)) - Expect(applySet).Should(HaveKeyWithValue("bgTargets.Standard.0.target", 5.55075)) - Expect(applySet).Should(HaveKeyWithValue("bgTargets.Standard.1.target", 5.55075)) - - Expect(applySet).Should(HaveKey("sleepSchedules")) - - applyObj := applySet.(primitive.M) - - actualUpdatedSleepSchedules := applyObj["sleepSchedules"] - - expectedUpdatedSleepSchedules := map[string]interface{}{ - "1": map[string]interface{}{ - "enabled": true, - "days": []interface{}{"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"}, - "start": 82800, - "end": 25200, - }, - "2": map[string]interface{}{ - "enabled": false, - "days": []interface{}{"sunday"}, - "start": 3600, - "end": 32400, - }, - } - - Expect(fmt.Sprintf("%v", actualUpdatedSleepSchedules)).To(Equal(fmt.Sprintf("%v", expectedUpdatedSleepSchedules))) - - Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - Expect(revertSet).Should(HaveKeyWithValue("bgTargets.Simple.0.target", 5.550747991045533)) - Expect(revertSet).Should(HaveKeyWithValue("bgTargets.Simple.1.target", 5.550747991045533)) - Expect(revertSet).Should(HaveKeyWithValue("bgTargets.Standard.0.target", 5.550747991045533)) - Expect(revertSet).Should(HaveKeyWithValue("bgTargets.Standard.1.target", 5.550747991045533)) - Expect(revertSet).Should(HaveKey("sleepSchedules")) - revertSetObj := revertSet.(primitive.M) - actualRevertSetSleepSchedules := revertSetObj["sleepSchedules"] - - expectedRevertSleepSchedules := []map[string]interface{}{ - { - "enabled": true, - "days": []interface{}{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}, - "start": 82800, - "end": 25200, - }, - { - "enabled": false, - "days": []interface{}{"Sunday"}, - "start": 3600, - "end": 32400, - }, - } - - Expect(fmt.Sprintf("%v", actualRevertSetSleepSchedules)).To(Equal(fmt.Sprintf("%v", expectedRevertSleepSchedules))) - - }) - - It("with make bgTraget updates and set _deduplicator", func() { - applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.PumpSettingsCarelink)) - - Expect(applySet).Should(HaveLen(3)) - Expect(revertUnset).Should(HaveLen(1)) - Expect(applyUnset).Should(BeNil()) - Expect(revertSet).Should(HaveLen(2)) - - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "LgRaGs4QkIBV9sHUjurpMt/ALU+7F7ZlU8xNxhkTQwQ="})) - Expect(applySet).Should(HaveKeyWithValue("bgTarget.0.target", 5.55075)) - Expect(applySet).Should(HaveKeyWithValue("bgTarget.1.target", 5.55075)) - - Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - Expect(revertSet).Should(HaveKeyWithValue("bgTarget.0.target", 5.550747991045533)) - Expect(revertSet).Should(HaveKeyWithValue("bgTarget.1.target", 5.550747991045533)) - }) - - It("with make bgTraget, bgTargetPhysicalActivity, bgTargetPreprandial updates and set _deduplicator", func() { - applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.PumpSettingsWithTarget)) - - Expect(applySet).Should(HaveLen(7)) - Expect(applyUnset).Should(BeNil()) - Expect(revertSet).Should(HaveLen(6)) - Expect(revertUnset).Should(HaveLen(1)) - - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "91MQsmPpTjboyucNKq23VOvWUx0afj3GSexzKvg8xPA="})) - Expect(applySet).Should(HaveKeyWithValue("bgTarget.0.target", 5.55075)) - Expect(applySet).Should(HaveKeyWithValue("bgTarget.0.high", 7.21597)) - Expect(applySet).Should(HaveKeyWithValue("bgTargetPhysicalActivity.low", 2.77537)) - Expect(applySet).Should(HaveKeyWithValue("bgTargetPhysicalActivity.high", 7.21597)) - Expect(applySet).Should(HaveKeyWithValue("bgTargetPreprandial.low", 2.77537)) - Expect(applySet).Should(HaveKeyWithValue("bgTargetPreprandial.high", 7.21597)) - - Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - Expect(revertSet).Should(HaveKeyWithValue("bgTarget.0.target", 5.550747991045533)) - Expect(revertSet).Should(HaveKeyWithValue("bgTarget.0.high", 7.2159723883591935)) - Expect(revertSet).Should(HaveKeyWithValue("bgTargetPhysicalActivity.low", 2.7753739955227665)) - Expect(revertSet).Should(HaveKeyWithValue("bgTargetPhysicalActivity.high", 7.2159723883591935)) - Expect(revertSet).Should(HaveKeyWithValue("bgTargetPreprandial.low", 2.7753739955227665)) - Expect(revertSet).Should(HaveKeyWithValue("bgTargetPreprandial.high", 7.2159723883591935)) - }) - - It("will male boluses updates and set _deduplicator", func() { - bsonObj := getBSONData(test.PumpSettingsWithBolusDatum) - applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) - - Expect(applySet).Should(HaveLen(3)) - Expect(revertUnset).Should(HaveLen(2)) - - Expect(applyUnset).Should(HaveLen(1)) - Expect(revertSet).Should(HaveLen(2)) - - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "l5e6HoVqMu3ZOUjqaky/m6ZNw+D0UFxbYw/fM9P4PXc="})) - Expect(applySet).Should(HaveKeyWithValue("units.bg", "mmol/L")) - revertSetObj := revertSet.(primitive.M) - Expect(applySet).Should(HaveKeyWithValue("boluses", revertSetObj["bolus"])) - Expect(applyUnset).Should(HaveKeyWithValue("bolus", "")) - - Expect(revertSet).Should(HaveKey("bolus")) - Expect(revertSet).Should(HaveKeyWithValue("units.bg", "mmol/l")) - Expect(revertUnset).Should(HaveKeyWithValue("boluses", "")) - Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - }) - }) - - Describe("wizard datum", func() { - It("only sets _deduplicator and bgInput, bgTarget and ignores the bolus and bolusId link", func() { - - bsonObj := getBSONData(test.WizardTandem) - Expect(bsonObj).Should(HaveKeyWithValue("bolus", "g2h6nohp5sdndpvl2l8kdete00lle4gt")) - - applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) - - Expect(applySet).Should(HaveLen(3)) - Expect(applyUnset).Should(HaveLen(5)) - - Expect(revertUnset).Should(HaveLen(1)) - Expect(revertSet).Should(HaveLen(7)) - - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "orP5cbifS8h0f3HWZcTOIf4B431HO1OReg9o1nmFnU4="})) - Expect(applySet).Should(HaveKeyWithValue("bgInput", 4.4406)) - Expect(applySet).Should(HaveKeyWithValue("bgTarget.target", 4.4406)) - Expect(applyUnset).Should(HaveKeyWithValue("rate", "")) - Expect(applyUnset).Should(HaveKeyWithValue("percent", "")) - Expect(applyUnset).Should(HaveKeyWithValue("duration", "")) - Expect(applyUnset).Should(HaveKeyWithValue("recommended.deliveryType", "")) - Expect(applyUnset).Should(HaveKeyWithValue("recommended.rate", "")) - - Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - Expect(revertSet).Should(HaveKeyWithValue("bgInput", 4.440598392836427)) - Expect(revertSet).Should(HaveKeyWithValue("bgTarget.target", 4.440598392836427)) - - Expect(revertSet).Should(HaveKeyWithValue("recommended.deliveryType", "scheduled")) - Expect(revertSet).Should(HaveKeyWithValue("recommended.rate", 0.7)) - Expect(revertSet).Should(HaveKeyWithValue("rate", 0.335)) - Expect(revertSet).Should(HaveKeyWithValue("duration", float64(300000))) - Expect(revertSet).Should(HaveKeyWithValue("percent", 0.47857142857142865)) - - }) - }) - - Describe("deviceEvent datum", func() { - It("sets _deduplicator and ignores the status and statusId link", func() { - bsonObj := getBSONData(test.ReservoirChangeWithStatus) - Expect(bsonObj).Should(HaveKeyWithValue("status", "cvv61jde62b6i28bgot57f18bor5au1n")) - applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) - - Expect(applySet).Should(HaveLen(1)) - Expect(revertUnset).Should(HaveLen(1)) - Expect(applyUnset).Should(BeNil()) - Expect(revertSet).Should(BeNil()) - - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "yahFM0LCaLowGnmbqHijnOpfwkR3Ot/YVK7K5n5yIHg="})) - Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - }) - - It("sets _deduplicator and ignores status suspended and will not update it", func() { - bsonObj := getBSONData(test.AlarmDeviceEventDatum) - Expect(bsonObj).Should(HaveKeyWithValue("status", "suspended")) - - applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) - - Expect(applySet).Should(HaveLen(1)) - Expect(revertUnset).Should(HaveLen(1)) - Expect(applyUnset).Should(BeNil()) - Expect(revertSet).Should(BeNil()) - - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "co0AMaEqrFrInC2Ek+HqbvmZRr9WTT0rEnZ8JXpm2Hg="})) - Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - }) - }) - - Describe("datum", func() { - It("payload will be migarted and _deduplicator set", func() { - bsonObj := getBSONData(test.CBGDexcomG5StringPayloadDatum) - applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) - - Expect(applySet).Should(HaveLen(2)) - Expect(revertUnset).Should(HaveLen(1)) - Expect(applyUnset).Should(BeNil()) - Expect(revertSet).Should(HaveLen(1)) - - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "Kix7EaZBCVwTaOR/LQPj6iJ08mFJOR/IR2nsvyDGtGA="})) - Expect(applySet).Should(HaveKeyWithValue("payload", map[string]interface{}{ - "transmitterId": "410X6M", - "transmitterTicks": 5.796922e+06, - "trend": "flat", - "trendRate": 0.6, - "trendRateUnits": "mg/dL/min", - "systemTime": "2017-11-05T18:56:51Z", - })) - Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - Expect(revertSet).Should(HaveKeyWithValue("payload", "{\"systemTime\":\"2017-11-05T18:56:51Z\",\"transmitterId\":\"410X6M\",\"transmitterTicks\":5796922,\"trend\":\"flat\",\"trendRate\":0.6,\"trendRateUnits\":\"mg/dL/min\"}")) - }) - It("payload will be migarted when empty and _deduplicator set", func() { - applySet, applyUnset, revertUnset, revertSet := setup(getBSONData(test.EmptyPayloadDatum)) - Expect(applySet).Should(HaveLen(1)) - Expect(revertUnset).Should(HaveLen(1)) - Expect(applyUnset).Should(HaveLen(1)) - Expect(revertSet).Should(HaveLen(1)) - - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "dcXIRasQiatLHLG8oUjiG2yNSKetWpkC7GDMQ8ZpM/c="})) - Expect(applyUnset).Should(HaveKeyWithValue("payload", "")) - Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - Expect(revertSet).Should(HaveKeyWithValue("payload", map[string]interface{}{})) - }) - It("annotations will be migrated with _deduplicator", func() { - bsonObj := getBSONData(test.CBGDexcomG5StringAnnotationsDatum) - applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) - - Expect(applySet).Should(HaveLen(2)) - Expect(revertUnset).Should(HaveLen(1)) - Expect(applyUnset).Should(BeNil()) - Expect(revertSet).Should(HaveLen(1)) - - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "Kix7EaZBCVwTaOR/LQPj6iJ08mFJOR/IR2nsvyDGtGA="})) - Expect(applySet).Should(HaveKeyWithValue("annotations", []interface{}{map[string]interface{}{ - "code": "bg/out-of-range", - "threshold": float64(40), - "value": "low", - }})) - - Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - Expect(revertSet).Should(HaveKeyWithValue("annotations", "[{\"code\":\"bg/out-of-range\",\"threshold\":40,\"value\":\"low\"}]")) - - }) - - It("extra fields will be remobved and _deduplicator applied", func() { - bsonObj := getBSONData(test.ExtraFieldsDatum) - applySet, applyUnset, revertUnset, revertSet := setup(bsonObj) - - Expect(applySet).Should(HaveLen(1)) - Expect(applyUnset).Should(HaveLen(4)) - Expect(revertSet).Should(HaveLen(4)) - Expect(revertUnset).Should(HaveLen(1)) - - Expect(applySet).Should(HaveKeyWithValue("_deduplicator", map[string]interface{}{"hash": "ZQYgkXIbB3hhhHAmCKivS46j2aHZMxhKzhA5w27PSFo="})) - Expect(applyUnset).Should(HaveKeyWithValue("index", "")) - Expect(applyUnset).Should(HaveKeyWithValue("jsDate", "")) - Expect(applyUnset).Should(HaveKeyWithValue("localTime", "")) - Expect(applyUnset).Should(HaveKeyWithValue("payload", "")) - - Expect(revertUnset).Should(HaveKeyWithValue("_deduplicator", "")) - - Expect(revertSet).Should(HaveKeyWithValue("index", float64(0))) - Expect(revertSet).Should(HaveKeyWithValue("jsDate", "2017-11-05T12:56:51.000Z")) - Expect(revertSet).Should(HaveKeyWithValue("localTime", "2017-11-05T12:56:51.000Z")) - Expect(revertSet).Should(HaveKeyWithValue("payload", map[string]interface{}{})) - - }) - - }) - }) - }) -}) From b5ff5d06f61cf6f0d12d5cedc477c8b657da9deb Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 21 Jun 2024 07:25:50 +1200 Subject: [PATCH 302/413] update devices --- data/deduplicator/deduplicator/device_deactivate_hash.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index d22f7c6bd8..ebf50dffc8 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -28,8 +28,8 @@ var DeviceDeactivateHashDeviceManufacturerDeviceModels = map[string][]string{ } var DeviceDeactivateLegacyHasheManufacturerDeviceModels = map[string][]string{ - "Tandem": {"T:Slim"}, - "InsuletOmniPod": {"Dash", "Eros"}, + "Tandem": {"T:Slim"}, + "Insulet": {"Dash", "Eros"}, //TODO: other devices here } From 59e50d343f516c8d57bf04ddc710fa720b54befa Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 25 Jun 2024 12:05:23 +1200 Subject: [PATCH 303/413] cleanup --- .../error_summary.sh | 21 ------------------- .../20231128_jellyfish_migration/readme.md | 10 +++++++++ .../rollback_jellyfish_migration.sh | 3 --- 3 files changed, 10 insertions(+), 24 deletions(-) delete mode 100755 migrations/20231128_jellyfish_migration/error_summary.sh delete mode 100644 migrations/20231128_jellyfish_migration/rollback_jellyfish_migration.sh diff --git a/migrations/20231128_jellyfish_migration/error_summary.sh b/migrations/20231128_jellyfish_migration/error_summary.sh deleted file mode 100755 index 8f18656c28..0000000000 --- a/migrations/20231128_jellyfish_migration/error_summary.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -INPUT_FILE=$1 -FIND_VAL=$2 - -echo "input_file: $INPUT_FILE" -parts=($(echo $INPUT_FILE | cut -d '.' -f1)) - -if [[ -z "$FIND_VAL" ]]; then - OUTPUT_FILE="${parts[0]}_summary.log" - echo "output_file: $OUTPUT_FILE" - cat $INPUT_FILE | jq '.error.detail // .error.errors[]?.detail' | sort | uniq -c | sort -nr >$OUTPUT_FILE -else - OUTPUT_FILE="${parts[0]}_detail.log" - echo "output_file: $OUTPUT_FILE" - cat $INPUT_FILE | jq -c "select(.error.detail == \"$FIND_VAL\") // select(.error.errors[]?.detail == \"$FIND_VAL\") \ - | if .error.code != null then \ - { id:._id, error: .error.code, detail: .error.detail, source: .error.source } else \ - { id:._id, source: .error.errors[].source } end \ - " >$OUTPUT_FILE -fi diff --git a/migrations/20231128_jellyfish_migration/readme.md b/migrations/20231128_jellyfish_migration/readme.md index 324823af16..475edd4584 100644 --- a/migrations/20231128_jellyfish_migration/readme.md +++ b/migrations/20231128_jellyfish_migration/readme.md @@ -32,3 +32,13 @@ GLOBAL OPTIONS: - run migration: `go run jellyfish_migration.go --user-id=924edd2e-b8fc-45ad-b3f4-3032bb6b0a45` + +- finding upload records with blobs + +``` +[ + { "$match": { "deviceManufacturers": { "$in": ["Tandem", "Insulet"] }, "client.private.blobId": { "$exists": true }}}, + { "$project": { "blobId": "$client.private.blobId", "_userId": 1, "deviceId": 1}}, + { "$group": { "_id": "$_userId", "detail": { "$push": "$$ROOT" }}} +] +``` \ No newline at end of file diff --git a/migrations/20231128_jellyfish_migration/rollback_jellyfish_migration.sh b/migrations/20231128_jellyfish_migration/rollback_jellyfish_migration.sh deleted file mode 100644 index 1bf656a592..0000000000 --- a/migrations/20231128_jellyfish_migration/rollback_jellyfish_migration.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -go run jellyfish_migration.go --cap=500000 --nop-percent=1 --query-limit=100 --query-batch=50 --rollback From 3c8d3e607ba76b7c4d449e4ffe514a09ca525a9d Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 25 Jun 2024 12:20:52 +1200 Subject: [PATCH 304/413] fix field types --- data/deduplicator/deduplicator/hash.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/deduplicator/deduplicator/hash.go b/data/deduplicator/deduplicator/hash.go index 57b47364f2..740eeff8f6 100644 --- a/data/deduplicator/deduplicator/hash.go +++ b/data/deduplicator/deduplicator/hash.go @@ -26,7 +26,7 @@ func AssignDataSetDataIdentityHashes(dataSetData data.Data, hasher HashType) err return errors.Wrap(err, "unable to generate identity hash for datum") } } else if hasher == LegacyHash { - fields, err := dataSetDatum.IdentityFields() + fields, err := dataSetDatum.LegacyIdentityFields() if err != nil { return errors.Wrap(err, "unable to gather legacy identity fields for datum") } From 1f63fc7f0e67c99e3381893f0e911567bd56117e Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 25 Jun 2024 15:33:02 +1200 Subject: [PATCH 305/413] updates from previous review --- data/types/common/day.go | 30 ++++--- data/types/common/day_test.go | 40 +++++----- .../jellyfish_migration.go | 55 +++++++------ .../jellyfish_migration.sh | 3 - .../20231128_jellyfish_migration/readme.md | 2 +- .../utils/data_migration.go | 79 ++++++++----------- .../utils/jellyfish_data.go | 5 +- prescription/test/prescription.go | 10 ++- 8 files changed, 118 insertions(+), 106 deletions(-) delete mode 100644 migrations/20231128_jellyfish_migration/jellyfish_migration.sh diff --git a/data/types/common/day.go b/data/types/common/day.go index 186164d884..ba82854449 100644 --- a/data/types/common/day.go +++ b/data/types/common/day.go @@ -1,5 +1,7 @@ package common +import "errors" + const ( DaySunday = "sunday" DayMonday = "monday" @@ -32,26 +34,34 @@ func (d DaysOfWeekByDayIndex) Swap(i int, j int) { } func (d DaysOfWeekByDayIndex) Less(i int, j int) bool { - return DayIndex(d[i]) < DayIndex(d[j]) + a, errA := DayIndex(d[i]) + if errA != nil { + return false + } + b, errB := DayIndex(d[j]) + if errB != nil { + return false + } + return a < b } -func DayIndex(day string) int { +func DayIndex(day string) (int, error) { switch day { case DaySunday: - return 1 + return 1, nil case DayMonday: - return 2 + return 2, nil case DayTuesday: - return 3 + return 3, nil case DayWednesday: - return 4 + return 4, nil case DayThursday: - return 5 + return 5, nil case DayFriday: - return 6 + return 6, nil case DaySaturday: - return 7 + return 7, nil default: - return 0 + return 0, errors.New("invalid day of the week") } } diff --git a/data/types/common/day_test.go b/data/types/common/day_test.go index c12e1a9390..ca93ed8158 100644 --- a/data/types/common/day_test.go +++ b/data/types/common/day_test.go @@ -1,6 +1,8 @@ package common_test import ( + "errors" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -52,25 +54,27 @@ var _ = Describe("Day", func() { Context("DayIndex", func() { DescribeTable("return the expected index when the day", - func(day string, expectedIndex int) { - Expect(common.DayIndex(day)).To(Equal(expectedIndex)) + func(day string, expectedIndex int, expectedErr error) { + actualIndex, actualError := common.DayIndex(day) + Expect(actualIndex).To(Equal(expectedIndex)) + Expect(actualError).To(Equal(expectedErr)) }, - Entry("is an empty string", "", 0), - Entry("is sunday", "sunday", 1), - Entry("is constant sunday", common.DaySunday, 1), - Entry("is monday", "monday", 2), - Entry("is constant monday", common.DayMonday, 2), - Entry("is tuesday", "tuesday", 3), - Entry("is constant tuesday", common.DayTuesday, 3), - Entry("is wednesday", "wednesday", 4), - Entry("isconstant wednesday", common.DayWednesday, 4), - Entry("is thursday", "thursday", 5), - Entry("is constant thursday", common.DayThursday, 5), - Entry("is friday", "friday", 6), - Entry("is constant friday", common.DayFriday, 6), - Entry("is saturday", "saturday", 7), - Entry("is constant saturday", common.DaySaturday, 7), - Entry("is an invalid string", "invalid", 0), + Entry("is an empty string", "", 0, errors.New("invalid day of the week")), + Entry("is sunday", "sunday", 1, nil), + Entry("is constant sunday", common.DaySunday, 1, nil), + Entry("is monday", "monday", 2, nil), + Entry("is constant monday", common.DayMonday, 2, nil), + Entry("is tuesday", "tuesday", 3, nil), + Entry("is constant tuesday", common.DayTuesday, 3, nil), + Entry("is wednesday", "wednesday", 4, nil), + Entry("isconstant wednesday", common.DayWednesday, 4, nil), + Entry("is thursday", "thursday", 5, nil), + Entry("is constant thursday", common.DayThursday, 5, nil), + Entry("is friday", "friday", 6, nil), + Entry("is constant friday", common.DayFriday, 6, nil), + Entry("is saturday", "saturday", 7, nil), + Entry("is constant saturday", common.DaySaturday, 7, nil), + Entry("is an invalid string", "invalid", 0, errors.New("invalid day of the week")), ) }) }) diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go index 9c129d4a7b..a71610bc71 100644 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ b/migrations/20231128_jellyfish_migration/jellyfish_migration.go @@ -24,11 +24,12 @@ type Migration struct { } type config struct { - cap int - uri string + recordLimit int + mongoURI string dryRun bool stopOnErr bool userID string + uploadID string lastUpdatedID string nopPercent int queryBatchSize int @@ -36,6 +37,15 @@ type config struct { } const DryRunFlag = "dry-run" +const StopOnErrorFlag = "stop-on-error" +const RecordLimitFlag = "record-limit" +const NopPercentFlag = "nop-percent" +const MongoURIFlag = "uri" +const DatumIDFlag = "datum-id" +const UserIDFlag = "user-id" +const UploadIDFlag = "upload-id" +const QueryLimitFlag = "query-limit" +const QueryBatchFlag = "query-batch" func main() { ctx := context.Background() @@ -56,13 +66,14 @@ func NewJellyfishMigration(ctx context.Context) *Migration { func (c *config) report() string { details := "\nMIGRATION DETAILS:\n" - details += fmt.Sprintf("- CAP\t\t\t[%d]\n", c.cap) - details += fmt.Sprintf("- AUDIT? \t\t[%t]\n", c.dryRun) - details += fmt.Sprintf("- STOP ON ERROR\t\t[%t]\n", c.stopOnErr) - details += fmt.Sprintf("- LAST PROCESSED ID\t[%s]\n", c.lastUpdatedID) - details += fmt.Sprintf("- USER ID\t\t[%s]\n", c.userID) - details += fmt.Sprintf("- QUERY BATCH\t\t[%d]\n", c.queryBatchSize) - details += fmt.Sprintf("- QUERY LIMIT\t\t[%d]\n", c.queryLimit) + details += fmt.Sprintf("- %s\t\t\t[%d]\n", RecordLimitFlag, c.recordLimit) + details += fmt.Sprintf("- %s? \t\t[%t]\n", DryRunFlag, c.dryRun) + details += fmt.Sprintf("- %s\t\t[%t]\n", StopOnErrorFlag, c.stopOnErr) + details += fmt.Sprintf("- %s\t[%s]\n", DatumIDFlag, c.lastUpdatedID) + details += fmt.Sprintf("- %s\t\t[%s]\n", UserIDFlag, c.userID) + details += fmt.Sprintf("- %s\t\t[%d]\n", QueryBatchFlag, c.queryBatchSize) + details += fmt.Sprintf("- %s\t\t[%d]\n", QueryLimitFlag, c.queryLimit) + details += fmt.Sprintf("- %s\t\t[%s]\n", UploadIDFlag, c.uploadID) return details } @@ -74,7 +85,7 @@ func (m *Migration) RunAndExit() { m.CLI().Action = func(ctx *cli.Context) error { var err error - m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(strings.TrimSpace(m.config.uri))) + m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(strings.TrimSpace(m.config.mongoURI))) if err != nil { return fmt.Errorf("unable to connect to MongoDB: %w", err) } @@ -90,7 +101,7 @@ func (m *Migration) RunAndExit() { utils.NewSettings( &m.config.dryRun, &m.config.stopOnErr, - &m.config.cap, + &m.config.recordLimit, &m.config.queryBatchSize, &m.config.queryLimit, pointer.FromBool(true), @@ -100,7 +111,7 @@ func (m *Migration) RunAndExit() { &m.config.lastUpdatedID, ) - log.Printf("%s", m.config.report()) + log.Println(m.config.report()) if err != nil { return fmt.Errorf("unable to create migration utils : %w", err) @@ -141,33 +152,33 @@ func (m *Migration) Initialize() error { Destination: &m.config.dryRun, }, cli.BoolFlag{ - Name: "stop-error", + Name: StopOnErrorFlag, Usage: "stop migration on error", Destination: &m.config.stopOnErr, }, cli.IntFlag{ - Name: "cap", + Name: RecordLimitFlag, Usage: "max number of records migrate", - Destination: &m.config.cap, + Destination: &m.config.recordLimit, Required: false, }, cli.IntFlag{ - Name: "nop-percent", + Name: NopPercentFlag, Usage: "how much of the oplog is NOP", Destination: &m.config.nopPercent, Value: 50, Required: false, }, cli.StringFlag{ - Name: "uri", + Name: MongoURIFlag, Usage: "mongo connection URI", - Destination: &m.config.uri, + Destination: &m.config.mongoURI, Required: false, //uri string comes from file called `uri` FilePath: "./uri", }, cli.StringFlag{ - Name: "datum-id", + Name: DatumIDFlag, Usage: "id of last datum updated", Destination: &m.config.lastUpdatedID, Required: false, @@ -175,20 +186,20 @@ func (m *Migration) Initialize() error { FilePath: "./lastProcessedId", }, cli.StringFlag{ - Name: "user-id", + Name: UserIDFlag, Usage: "id of single user to migrate", Destination: &m.config.userID, Required: false, }, cli.IntFlag{ - Name: "query-limit", + Name: QueryLimitFlag, Usage: "max number of items to return", Destination: &m.config.queryLimit, Value: 50000, Required: false, }, cli.IntFlag{ - Name: "query-batch", + Name: QueryBatchFlag, Usage: "max number of items in each query batch", Destination: &m.config.queryBatchSize, Value: 10000, diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.sh b/migrations/20231128_jellyfish_migration/jellyfish_migration.sh deleted file mode 100644 index 8719cffa83..0000000000 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -go run jellyfish_migration.go --cap=500000 --nop-percent=1 --query-limit=100 --query-batch=50 diff --git a/migrations/20231128_jellyfish_migration/readme.md b/migrations/20231128_jellyfish_migration/readme.md index 475edd4584..a21b15ca52 100644 --- a/migrations/20231128_jellyfish_migration/readme.md +++ b/migrations/20231128_jellyfish_migration/readme.md @@ -14,7 +14,7 @@ ``` GLOBAL OPTIONS: --dry-run, -n dry run only; do not migrate - --stop-error stop migration on error + --stop-on-error stop migration on error --audit run audit --cap value max number of records migrate (default: 0) --nop-percent value how much of the oplog is NOP (default: 50) diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go index 4f05abd180..ffb7f052f8 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration.go @@ -43,11 +43,11 @@ type Settings struct { QueryBatchSize int QueryBatchLimit int - capacity *int + RecordLimit *int writeToDisk bool } -func NewSettings(dryRun *bool, stopOnErr *bool, capacity *int, queryBatch *int, queryLimit *int, writeToDisk *bool) *Settings { +func NewSettings(dryRun *bool, stopOnErr *bool, recordLimit *int, queryBatchSize *int, queryBatchLimit *int, writeToDisk *bool) *Settings { settings := &Settings{ writeToDisk: false, DryRun: true, @@ -65,15 +65,15 @@ func NewSettings(dryRun *bool, stopOnErr *bool, capacity *int, queryBatch *int, if writeToDisk != nil { settings.writeToDisk = *writeToDisk } - if queryBatch != nil { - settings.QueryBatchSize = *queryBatch + if queryBatchSize != nil { + settings.QueryBatchSize = *queryBatchSize } - if queryLimit != nil { - settings.QueryBatchLimit = *queryLimit + if queryBatchLimit != nil { + settings.QueryBatchLimit = *queryBatchLimit } - if capacity != nil && *capacity > 0 { - settings.capacity = capacity - log.Printf("capped at %d items", *settings.capacity) + if recordLimit != nil && *recordLimit > 0 { + settings.RecordLimit = recordLimit + log.Printf("capped at %d items", *settings.RecordLimit) } return settings } @@ -88,7 +88,7 @@ type DataMigration struct { errorsCount int updatedCount int fetchedCount int - lastUpdatedID string + lastUpdatedID *string startedAt time.Time mongoInstanceChecker MongoInstanceCheck } @@ -123,10 +123,9 @@ func NewMigration(ctx context.Context, settings *Settings, checker MongoInstance updatedCount: 0, fetchedCount: 0, startedAt: time.Now(), + lastUpdatedID: lastID, } - if lastID != nil { - m.lastUpdatedID = *lastID - } + return m, nil } @@ -159,19 +158,19 @@ func (m *DataMigration) Execute( for queryFn(m) { count, err := updateFn(m) if err != nil { - m.writeErrors(nil) + m.writeErrors() return err } m.updatesApplied(count) if m.completeUpdates() { break } - m.writeErrors(nil) - m.writeAudit(nil) + m.writeErrors() + m.writeAudit() } m.GetStats().report() - m.writeErrors(nil) - m.writeAudit(nil) + m.writeErrors() + m.writeAudit() return nil } @@ -196,16 +195,16 @@ func (m *DataMigration) updatesApplied(updatedCount int) { } func (m *DataMigration) completeUpdates() bool { - capacity := m.settings.capacity - if capacity != nil { - stats := m.GetStats() - - percent := (float64(stats.Fetched) * float64(100)) / float64(*capacity) - - log.Printf("processed %.0f %% of %d records and applied %d changes", percent, *capacity, stats.Applied) - - if *capacity <= stats.Applied || *capacity <= stats.Fetched { - log.Printf("cap [%d] updates applied [%d] fetched [%d]", *capacity, stats.Applied, stats.Fetched) + recordLimit := m.settings.RecordLimit + stats := m.GetStats() + if recordLimit == nil { + log.Printf("updates applied [%d] fetched [%d]", stats.Applied, stats.Fetched) + } else { + percent := (float64(stats.Fetched) * float64(100)) / float64(*recordLimit) + log.Printf("processed %.0f %% of %d records and applied %d changes", percent, *recordLimit, stats.Applied) + + if *recordLimit <= stats.Applied || *recordLimit <= stats.Fetched { + log.Printf("recordLimit [%d] updates applied [%d] fetched [%d]", *recordLimit, stats.Applied, stats.Fetched) return true } } @@ -217,8 +216,8 @@ func (m *DataMigration) GetUpdates() []mongo.WriteModel { } func (m *DataMigration) SetLastProcessed(lastID string) { - m.lastUpdatedID = lastID - m.writeLastProcessed(m.lastUpdatedID) + m.lastUpdatedID = &lastID + m.writeLastProcessed(*m.lastUpdatedID) } func (m *DataMigration) UpdateFetchedCount() { @@ -235,17 +234,17 @@ func (m *DataMigration) GetStats() MigrationStats { } } -func (m *DataMigration) GetLastID() string { +func (m *DataMigration) GetLastID() *string { return m.lastUpdatedID } func (m *DataMigration) OnError(data ErrorData) { - m.errorsCount++ - m.groupedErrors[data.ItemType] = append(m.groupedErrors[data.ItemType], data) if m.settings.StopOnErr { log.Printf("[_id=%s] %s %s\n", data.ItemID, data.Msg, data.Error.Error()) os.Exit(1) } + m.errorsCount++ + m.groupedErrors[data.ItemType] = append(m.groupedErrors[data.ItemType], data) } func (m *DataMigration) CheckMongoInstance() error { @@ -266,16 +265,11 @@ func (c MigrationStats) report() { log.Printf("elapsed [%s] for [%d] fetched [%d] updates applied with [%d] errors\n", c.Elapsed, c.Fetched, c.Applied, c.Errored) } -func (m *DataMigration) writeErrors(groupLimit *int) { +func (m *DataMigration) writeErrors() { if !m.settings.writeToDisk { m.groupedErrors = map[string][]ErrorData{} } for group, errors := range m.groupedErrors { - if groupLimit != nil { - if len(errors) < *groupLimit { - continue - } - } f, err := m.createFile("error", group, "%s.log") if err != nil { log.Println(err) @@ -294,17 +288,12 @@ func (m *DataMigration) writeErrors(groupLimit *int) { } } -func (m *DataMigration) writeAudit(groupLimit *int) { +func (m *DataMigration) writeAudit() { if !m.settings.writeToDisk || !m.settings.DryRun { m.groupedDiffs = map[string][]UpdateData{} return } for group, diffs := range m.groupedDiffs { - if groupLimit != nil { - if len(diffs) < *groupLimit { - continue - } - } f, err := m.createFile("audit", group, "%s.json") if err != nil { log.Println(err) diff --git a/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go b/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go index 4529f85e63..1c1954cb34 100644 --- a/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go +++ b/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go @@ -9,7 +9,6 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" "github.com/tidepool-org/platform/data/deduplicator/deduplicator" - "github.com/tidepool-org/platform/pointer" ) func jellyfishQuery(settings Settings, userID *string, lastFetchedID *string) (bson.M, *options.FindOptions) { @@ -52,7 +51,7 @@ var JellyfishDataQueryFn = func(m *DataMigration) bool { selector, opts := jellyfishQuery( settings, nil, - pointer.FromString(m.GetLastID()), + m.GetLastID(), ) opts.Projection = bson.M{"_id": 1} @@ -139,7 +138,7 @@ var JellyfishUploadQueryFn = func(m *DataMigration) bool { selector, opts := jellyfishQuery( settings, nil, - pointer.FromString(m.GetLastID()), + m.GetLastID(), ) opts.Projection = bson.M{"_id": 1} diff --git a/prescription/test/prescription.go b/prescription/test/prescription.go index 0120d9d221..f367cdf167 100644 --- a/prescription/test/prescription.go +++ b/prescription/test/prescription.go @@ -6,10 +6,12 @@ import ( dataBloodGlucoseTest "github.com/tidepool-org/platform/data/blood/glucose/test" "github.com/tidepool-org/platform/data/types/settings/pump" + dataTypesSettingsPump "github.com/tidepool-org/platform/data/types/settings/pump" "github.com/google/uuid" "github.com/tidepool-org/platform/data/blood/glucose" + testUtils "github.com/tidepool-org/platform/test" userTest "github.com/tidepool-org/platform/user/test" @@ -180,7 +182,7 @@ func RandomInitialSettings() *prescription.InitialSettings { func RandomCalculator() *prescription.Calculator { return &prescription.Calculator{ - Method: pointer.FromString(test.RandomStringFromArray(prescription.AllowedCalculatorMethods())), + Method: pointer.FromString(testUtils.RandomStringFromArray(prescription.AllowedCalculatorMethods())), RecommendedBasalRate: pointer.FromFloat64(test.RandomFloat64FromRange(0, 100)), RecommendedCarbohydrateRatio: pointer.FromFloat64(test.RandomFloat64FromRange(0, 100)), RecommendedInsulinSensitivity: pointer.FromFloat64(test.RandomFloat64FromRange(0, 100)), @@ -235,10 +237,10 @@ func RandomBloodGlucoseTargetStart(startMinimum int) *pump.BloodGlucoseTargetSta func RandomInsulinModel() *string { validInsulinTypes := []string{ - pump.InsulinModelModelTypeRapidAdult, - pump.InsulinModelModelTypeRapidChild, + dataTypesSettingsPump.InsulinModelModelTypeRapidAdult, + dataTypesSettingsPump.InsulinModelModelTypeRapidChild, } - return pointer.FromString(test.RandomStringFromArray(validInsulinTypes)) + return pointer.FromString(testUtils.RandomStringFromArray(validInsulinTypes)) } func RandomDeviceID() string { From 8d15dc873e0232fc6be447d4318707599a7052e6 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 25 Jun 2024 16:36:35 +1200 Subject: [PATCH 306/413] review updates --- data/types/common/day_test.go | 2 +- .../override/settings/pump/pump_test.go | 33 +++++++++---------- data/types/settings/cgm/scheduled_alert.go | 4 +-- .../settings/cgm/test/scheduled_alert.go | 4 +-- data/types/settings/pump/bolus.go | 18 +++++----- .../settings/pump/override_preset_test.go | 8 ++--- data/types/settings/pump/pump_test.go | 18 +++++----- data/types/settings/pump/sleep_schedule.go | 6 ++-- .../settings/pump/sleep_schedule_test.go | 11 ++++--- data/types/settings/pump/test/bolus.go | 26 +++++++++------ 10 files changed, 68 insertions(+), 62 deletions(-) diff --git a/data/types/common/day_test.go b/data/types/common/day_test.go index ca93ed8158..b0d7a96ea0 100644 --- a/data/types/common/day_test.go +++ b/data/types/common/day_test.go @@ -67,7 +67,7 @@ var _ = Describe("Day", func() { Entry("is tuesday", "tuesday", 3, nil), Entry("is constant tuesday", common.DayTuesday, 3, nil), Entry("is wednesday", "wednesday", 4, nil), - Entry("isconstant wednesday", common.DayWednesday, 4, nil), + Entry("is constant wednesday", common.DayWednesday, 4, nil), Entry("is thursday", "thursday", 5, nil), Entry("is constant thursday", common.DayThursday, 5, nil), Entry("is friday", "friday", 6, nil), diff --git a/data/types/device/override/settings/pump/pump_test.go b/data/types/device/override/settings/pump/pump_test.go index d867f54552..e1fd7dad3f 100644 --- a/data/types/device/override/settings/pump/pump_test.go +++ b/data/types/device/override/settings/pump/pump_test.go @@ -8,7 +8,6 @@ import ( dataBloodGlucoseTest "github.com/tidepool-org/platform/data/blood/glucose/test" dataNormalizer "github.com/tidepool-org/platform/data/normalizer" dataTypesDevice "github.com/tidepool-org/platform/data/types/device" - "github.com/tidepool-org/platform/data/types/device/override/settings/pump" dataTypesDeviceOverrideSettingsPump "github.com/tidepool-org/platform/data/types/device/override/settings/pump" dataTypesDeviceOverrideSettingsPumpTest "github.com/tidepool-org/platform/data/types/device/override/settings/pump/test" dataTypesTest "github.com/tidepool-org/platform/data/types/test" @@ -370,7 +369,7 @@ var _ = Describe("Pump", func() { datum.Duration = pointer.FromInt(-1) datum.DurationExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, pump.DurationMaximum), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/duration", NewMeta()), ), Entry("duration; in range (lower)", pointer.FromString("mmol/L"), @@ -389,15 +388,15 @@ var _ = Describe("Pump", func() { Entry("duration; out of range (upper)", pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { - datum.Duration = pointer.FromInt(pump.DurationMaximum + 1) + datum.Duration = pointer.FromInt(604800000 + 1) datum.DurationExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(pump.DurationMaximum+1, 0, pump.DurationMaximum), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604800000+1, 0, 604800000), "/duration", NewMeta()), ), Entry("duration expected missing", pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { - datum.Duration = pointer.FromInt(test.RandomIntFromRange(0, pump.DurationMaximum)) + datum.Duration = pointer.FromInt(test.RandomIntFromRange(0, 604800000)) datum.DurationExpected = nil }, ), @@ -407,7 +406,7 @@ var _ = Describe("Pump", func() { datum.Duration = nil datum.DurationExpected = pointer.FromInt(-1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, pump.DurationMaximum), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/expectedDuration", NewMeta()), ), Entry("duration expected; duration missing; in range (lower)", pointer.FromString("mmol/L"), @@ -420,16 +419,16 @@ var _ = Describe("Pump", func() { pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { datum.Duration = nil - datum.DurationExpected = pointer.FromInt(pump.DurationMaximum) + datum.DurationExpected = pointer.FromInt(604800000) }, ), Entry("duration expected; duration missing; out of range (upper)", pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { datum.Duration = nil - datum.DurationExpected = pointer.FromInt(pump.DurationMaximum + 1) + datum.DurationExpected = pointer.FromInt(604800000 + 1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(pump.DurationMaximum+1, 0, pump.DurationMaximum), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604800000+1, 0, 604800000), "/expectedDuration", NewMeta()), ), Entry("duration expected; duration out of range; out of range (lower)", pointer.FromString("mmol/L"), @@ -437,8 +436,8 @@ var _ = Describe("Pump", func() { datum.Duration = pointer.FromInt(-1) datum.DurationExpected = pointer.FromInt(-1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, pump.DurationMaximum), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, pump.DurationMaximum), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/expectedDuration", NewMeta()), ), Entry("duration expected; duration out of range; in range (lower)", pointer.FromString("mmol/L"), @@ -446,7 +445,7 @@ var _ = Describe("Pump", func() { datum.Duration = pointer.FromInt(-1) datum.DurationExpected = pointer.FromInt(0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, pump.DurationMaximum), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/duration", NewMeta()), ), Entry("duration expected; out of range (lower)", pointer.FromString("mmol/L"), @@ -454,7 +453,7 @@ var _ = Describe("Pump", func() { datum.Duration = pointer.FromInt(3600) datum.DurationExpected = pointer.FromInt(3599) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(3599, 3600, pump.DurationMaximum), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(3599, 3600, 604800000), "/expectedDuration", NewMeta()), ), Entry("duration expected; in range (lower)", pointer.FromString("mmol/L"), @@ -474,9 +473,9 @@ var _ = Describe("Pump", func() { pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { datum.Duration = pointer.FromInt(3600) - datum.DurationExpected = pointer.FromInt(pump.DurationMaximum + 1) + datum.DurationExpected = pointer.FromInt(604800000 + 1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(pump.DurationMaximum+1, 3600, pump.DurationMaximum), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604800000+1, 3600, 604800000), "/expectedDuration", NewMeta()), ), Entry("units mmol/L; blood glucose target missing", pointer.FromString("mmol/L"), @@ -697,8 +696,8 @@ var _ = Describe("Pump", func() { errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/overrideType", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueExists(), "/overridePreset", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"automatic", "manual"}), "/method", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, pump.DurationMaximum), "/duration", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, pump.DurationMaximum), "/expectedDuration", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/duration", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/expectedDuration", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(0.09, 0.1, 10.0), "/basalRateScaleFactor", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(0.09, 0.1, 10.0), "/carbRatioScaleFactor", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(0.09, 0.1, 10.0), "/insulinSensitivityScaleFactor", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), diff --git a/data/types/settings/cgm/scheduled_alert.go b/data/types/settings/cgm/scheduled_alert.go index 9a447aff38..ac9eb59e5c 100644 --- a/data/types/settings/cgm/scheduled_alert.go +++ b/data/types/settings/cgm/scheduled_alert.go @@ -3,7 +3,7 @@ package cgm import ( "strconv" - "github.com/tidepool-org/platform/data/types/common" + dataTypesCommon "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/structure" structureValidator "github.com/tidepool-org/platform/structure/validator" ) @@ -88,7 +88,7 @@ func (s *ScheduledAlert) Parse(parser structure.ObjectParser) { func (s *ScheduledAlert) Validate(validator structure.Validator) { validator.String("name", s.Name).NotEmpty().LengthLessThanOrEqualTo(ScheduledAlertNameLengthMaximum) - validator.StringArray("days", s.Days).Exists().EachOneOf(common.DaysOfWeek()...).EachUnique() + validator.StringArray("days", s.Days).Exists().EachOneOf(dataTypesCommon.DaysOfWeek()...).EachUnique() validator.Int("start", s.Start).Exists().InRange(ScheduledAlertStartMinimum, ScheduledAlertStartMaximum) validator.Int("end", s.End).Exists().InRange(ScheduledAlertEndMinimum, ScheduledAlertEndMaximum) if alertsValidator := validator.WithReference("alerts"); s.Alerts != nil { diff --git a/data/types/settings/cgm/test/scheduled_alert.go b/data/types/settings/cgm/test/scheduled_alert.go index 11c3c255d7..ac7af02a8e 100644 --- a/data/types/settings/cgm/test/scheduled_alert.go +++ b/data/types/settings/cgm/test/scheduled_alert.go @@ -1,7 +1,7 @@ package test import ( - "github.com/tidepool-org/platform/data/types/common" + dataTypesCommon "github.com/tidepool-org/platform/data/types/common" dataTypesSettingsCgm "github.com/tidepool-org/platform/data/types/settings/cgm" "github.com/tidepool-org/platform/pointer" "github.com/tidepool-org/platform/test" @@ -40,7 +40,7 @@ func NewArrayFromScheduledAlerts(datum *dataTypesSettingsCgm.ScheduledAlerts, ob func RandomScheduledAlert() *dataTypesSettingsCgm.ScheduledAlert { datum := dataTypesSettingsCgm.NewScheduledAlert() datum.Name = pointer.FromString(test.RandomStringFromRange(1, dataTypesSettingsCgm.ScheduledAlertNameLengthMaximum)) - datum.Days = pointer.FromStringArray(test.RandomStringArrayFromRangeAndArrayWithoutDuplicates(1, len(common.DaysOfWeek()), common.DaysOfWeek())) + datum.Days = pointer.FromStringArray(test.RandomStringArrayFromRangeAndArrayWithoutDuplicates(1, len(dataTypesCommon.DaysOfWeek()), dataTypesCommon.DaysOfWeek())) datum.Start = pointer.FromInt(test.RandomIntFromRange(dataTypesSettingsCgm.ScheduledAlertStartMinimum, dataTypesSettingsCgm.ScheduledAlertStartMaximum)) datum.End = pointer.FromInt(test.RandomIntFromRange(dataTypesSettingsCgm.ScheduledAlertEndMinimum, dataTypesSettingsCgm.ScheduledAlertEndMaximum)) datum.Alerts = RandomAlerts() diff --git a/data/types/settings/pump/bolus.go b/data/types/settings/pump/bolus.go index 629d5964fa..dc0cbbdcde 100644 --- a/data/types/settings/pump/bolus.go +++ b/data/types/settings/pump/bolus.go @@ -78,28 +78,28 @@ func (b *BolusMap) Parse(parser structure.ObjectParser) { } } -func (b *BolusMap) Normalize(normalizer data.Normalizer) { +func (b *BolusMap) Validate(validator structure.Validator) { for _, name := range b.sortedNames() { + datumValidator := validator.WithReference(name) if datum := b.Get(name); datum != nil { - datum.Normalize(normalizer.WithReference(name)) + datum.Validate(datumValidator) + } else { + datumValidator.ReportError(structureValidator.ErrorValueNotExists()) } } } -func (b *BolusMap) Validate(validator structure.Validator) { +func (b *BolusMap) Normalize(normalizer data.Normalizer) { for _, name := range b.sortedNames() { - datumValidator := validator.WithReference(name) if datum := b.Get(name); datum != nil { - datum.Validate(datumValidator) - } else { - datumValidator.ReportError(structureValidator.ErrorValueNotExists()) + datum.Normalize(normalizer.WithReference(name)) } } } func (b *BolusMap) Get(name string) *Bolus { - if datumArray, exists := (*b)[name]; exists { - return datumArray + if datum, exists := (*b)[name]; exists { + return datum } return nil } diff --git a/data/types/settings/pump/override_preset_test.go b/data/types/settings/pump/override_preset_test.go index e768a4e206..3050cbdd6c 100644 --- a/data/types/settings/pump/override_preset_test.go +++ b/data/types/settings/pump/override_preset_test.go @@ -192,7 +192,7 @@ var _ = Describe("OverridePreset", func() { func(datum *dataTypesSettingsPump.OverridePreset, unitsBloodGlucose *string) { datum.Duration = pointer.FromInt(-1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-1, 0, dataTypesSettingsPump.DurationMaximum), "/duration"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/duration"), ), Entry("duration; in range (lower)", pointer.FromString("mmol/L"), @@ -203,7 +203,7 @@ var _ = Describe("OverridePreset", func() { Entry("duration; in range (upper)", pointer.FromString("mmol/L"), func(datum *dataTypesSettingsPump.OverridePreset, unitsBloodGlucose *string) { - datum.Duration = pointer.FromInt(dataTypesSettingsPump.DurationMaximum) + datum.Duration = pointer.FromInt(604800000) }, ), Entry("duration; out of range (upper)", @@ -211,7 +211,7 @@ var _ = Describe("OverridePreset", func() { func(datum *dataTypesSettingsPump.OverridePreset, unitsBloodGlucose *string) { datum.Duration = pointer.FromInt(604800001) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(604800001, 0, dataTypesSettingsPump.DurationMaximum), "/duration"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(604800001, 0, 604800000), "/duration"), ), Entry("units mmol/L; blood glucose target missing", pointer.FromString("mmol/L"), @@ -388,7 +388,7 @@ var _ = Describe("OverridePreset", func() { datum.InsulinSensitivityScaleFactor = pointer.FromFloat64(0.09) }, errorsTest.WithPointerSource(structureValidator.ErrorValueEmpty(), "/abbreviation"), - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-1, 0, dataTypesSettingsPump.DurationMaximum), "/duration"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/duration"), errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(0.09, 0.1, 10.0), "/basalRateScaleFactor"), errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(0.09, 0.1, 10.0), "/carbRatioScaleFactor"), errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(0.09, 0.1, 10.0), "/insulinSensitivityScaleFactor"), diff --git a/data/types/settings/pump/pump_test.go b/data/types/settings/pump/pump_test.go index 64a65fd75f..d79aa12522 100644 --- a/data/types/settings/pump/pump_test.go +++ b/data/types/settings/pump/pump_test.go @@ -288,17 +288,17 @@ var _ = Describe("Pump", func() { Entry("bolus invalid", pointer.FromString("mmol/L"), func(datum *pump.Pump, unitsBloodGlucose *string) { - datum.Boluses = nil datum.Bolus = pumpTest.NewRandomBolus() datum.Bolus.Calculator.Enabled = nil + datum.Boluses = nil }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/bolus/calculator/enabled", pumpTest.NewMeta()), ), Entry("bolus valid", pointer.FromString("mmol/L"), func(datum *pump.Pump, unitsBloodGlucose *string) { - datum.Boluses = nil datum.Bolus = pumpTest.NewRandomBolus() + datum.Boluses = nil }, ), Entry("boluses missing", @@ -665,12 +665,6 @@ var _ = Describe("Pump", func() { datum.SleepSchedules = pump.NewSleepScheduleMap() }, ), - Entry("sleep schedules valid", - pointer.FromString("mmol/L"), - func(datum *pump.Pump, unitsBloodGlucose *string) { - datum.SleepSchedules = pumpTest.RandomSleepSchedules(3) - }, - ), Entry("sleep schedules invalid", pointer.FromString("mmol/L"), func(datum *pump.Pump, unitsBloodGlucose *string) { @@ -682,6 +676,12 @@ var _ = Describe("Pump", func() { pump.SleepSchedulesMidnightOffsetMaximum), fmt.Sprintf("/sleepSchedules/%s/end", pumpTest.SleepScheduleName(0)), pumpTest.NewMeta()), ), + Entry("sleep schedules valid", + pointer.FromString("mmol/L"), + func(datum *pump.Pump, unitsBloodGlucose *string) { + datum.SleepSchedules = pumpTest.RandomSleepSchedules(3) + }, + ), Entry("software version missing", pointer.FromString("mmol/L"), func(datum *pump.Pump, units *string) { datum.SoftwareVersion = nil }, @@ -737,9 +737,9 @@ var _ = Describe("Pump", func() { datum.BloodGlucoseTargetSchedules = nil datum.BloodGlucoseTargetPhysicalActivity = dataBloodGlucose.NewTarget() datum.BloodGlucoseTargetPreprandial = dataBloodGlucose.NewTarget() - datum.Boluses = nil datum.Bolus = pumpTest.NewRandomBolus() datum.Bolus.Extended.Enabled = nil + datum.Boluses = nil invalidCarbohydrateRatioSchedule := pumpTest.NewCarbohydrateRatioStartArray() (*invalidCarbohydrateRatioSchedule)[0].Start = nil datum.CarbohydrateRatioSchedule = invalidCarbohydrateRatioSchedule diff --git a/data/types/settings/pump/sleep_schedule.go b/data/types/settings/pump/sleep_schedule.go index a3858bcb74..e1854bcfbc 100644 --- a/data/types/settings/pump/sleep_schedule.go +++ b/data/types/settings/pump/sleep_schedule.go @@ -4,7 +4,7 @@ import ( "sort" "github.com/tidepool-org/platform/data" - "github.com/tidepool-org/platform/data/types/common" + dataTypesCommon "github.com/tidepool-org/platform/data/types/common" "github.com/tidepool-org/platform/structure" structureValidator "github.com/tidepool-org/platform/structure/validator" ) @@ -106,7 +106,7 @@ func (s *SleepSchedule) Validate(validator structure.Validator) { validator.Bool("enabled", s.Enabled).Exists() if s.Enabled != nil { if *s.Enabled { - validator.StringArray("days", s.Days).Exists().EachOneOf(common.DaysOfWeek()...).EachUnique() + validator.StringArray("days", s.Days).Exists().EachOneOf(dataTypesCommon.DaysOfWeek()...).EachUnique() validator.Int("start", s.Start).Exists().InRange(SleepSchedulesMidnightOffsetMinimum, SleepSchedulesMidnightOffsetMaximum) validator.Int("end", s.End).Exists().InRange(SleepSchedulesMidnightOffsetMinimum, SleepSchedulesMidnightOffsetMaximum) } @@ -115,6 +115,6 @@ func (s *SleepSchedule) Validate(validator structure.Validator) { func (s *SleepSchedule) Normalize(normalizer data.Normalizer) { if s.Days != nil { - sort.Sort(common.DaysOfWeekByDayIndex(*s.Days)) + sort.Sort(dataTypesCommon.DaysOfWeekByDayIndex(*s.Days)) } } diff --git a/data/types/settings/pump/sleep_schedule_test.go b/data/types/settings/pump/sleep_schedule_test.go index 3c0f2d7b39..b0710b821f 100644 --- a/data/types/settings/pump/sleep_schedule_test.go +++ b/data/types/settings/pump/sleep_schedule_test.go @@ -49,7 +49,7 @@ var _ = Describe("SleepSchedule", func() { ), Entry("has many", func(datum *dataTypesSettingsPump.SleepScheduleMap) { - *datum = *dataTypesSettingsPumpTest.RandomSleepSchedules(19) + *datum = *dataTypesSettingsPumpTest.RandomSleepSchedules(3) }, ), Entry("entry missing", @@ -106,11 +106,10 @@ var _ = Describe("SleepSchedule", func() { Entry("succeeds", func(datum *dataTypesSettingsPump.SleepSchedule) {}, ), - Entry("enabled empty", + Entry("enabled missing", func(datum *dataTypesSettingsPump.SleepSchedule) { datum.Enabled = nil }, errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/enabled"), ), - Entry("days missing", func(datum *dataTypesSettingsPump.SleepSchedule) { datum.Days = nil @@ -145,7 +144,8 @@ var _ = Describe("SleepSchedule", func() { func(datum *dataTypesSettingsPump.SleepSchedule) { datum.Start = pointer.FromInt(-1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-1, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange( + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum-1, dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum, dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum), "/start"), ), @@ -178,7 +178,8 @@ var _ = Describe("SleepSchedule", func() { func(datum *dataTypesSettingsPump.SleepSchedule) { datum.End = pointer.FromInt(-1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-1, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange( + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum-1, dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum, dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum), "/end"), ), diff --git a/data/types/settings/pump/test/bolus.go b/data/types/settings/pump/test/bolus.go index 2a24e39ddb..52cac453c2 100644 --- a/data/types/settings/pump/test/bolus.go +++ b/data/types/settings/pump/test/bolus.go @@ -3,23 +3,23 @@ package test import ( "fmt" - "github.com/tidepool-org/platform/data/types/settings/pump" + dataTypesSettingsPump "github.com/tidepool-org/platform/data/types/settings/pump" "github.com/tidepool-org/platform/test" ) -func NewRandomBolus() *pump.Bolus { - datum := pump.NewBolus() +func NewRandomBolus() *dataTypesSettingsPump.Bolus { + datum := dataTypesSettingsPump.NewBolus() datum.AmountMaximum = NewBolusAmountMaximum() datum.Extended = NewBolusExtended() datum.Calculator = NewBolusCalculator() return datum } -func CloneBolus(datum *pump.Bolus) *pump.Bolus { +func CloneBolus(datum *dataTypesSettingsPump.Bolus) *dataTypesSettingsPump.Bolus { if datum == nil { return nil } - clone := pump.NewBolus() + clone := dataTypesSettingsPump.NewBolus() clone.AmountMaximum = CloneBolusAmountMaximum(datum.AmountMaximum) clone.Extended = CloneBolusExtended(datum.Extended) clone.Calculator = CloneBolusCalculator(datum.Calculator) @@ -30,19 +30,25 @@ func BolusName(index int) string { return fmt.Sprintf("bolus-%d", index) } -func NewRandomBolusMap(minimumLength int, maximumLength int) *pump.BolusMap { - datum := pump.NewBolusMap() - for count := test.RandomIntFromRange(minimumLength, maximumLength); count > 0; count-- { +func NewRandomBolusMap(minimumLength int, maximumLength int) *dataTypesSettingsPump.BolusMap { + datum := dataTypesSettingsPump.NewBolusMap() + count := test.RandomIntFromRange(minimumLength, maximumLength) + if count == 0 { + return nil + } + + for i := 0; i < count; i++ { datum.Set(BolusName(count), NewRandomBolus()) } + return datum } -func CloneBolusMap(datum *pump.BolusMap) *pump.BolusMap { +func CloneBolusMap(datum *dataTypesSettingsPump.BolusMap) *dataTypesSettingsPump.BolusMap { if datum == nil { return nil } - clone := pump.NewBolusMap() + clone := dataTypesSettingsPump.NewBolusMap() for k, v := range *datum { (*clone)[k] = CloneBolus(v) } From 0f7dda1eb9801266d7728188ab739b625b8f7af9 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 26 Jun 2024 15:10:16 +1200 Subject: [PATCH 307/413] review updates --- data/types/settings/pump/pump_test.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/data/types/settings/pump/pump_test.go b/data/types/settings/pump/pump_test.go index d79aa12522..7f4bc1cf84 100644 --- a/data/types/settings/pump/pump_test.go +++ b/data/types/settings/pump/pump_test.go @@ -309,14 +309,16 @@ var _ = Describe("Pump", func() { pointer.FromString("mmol/L"), func(datum *pump.Pump, unitsBloodGlucose *string) { datum.Bolus = nil - datum.Boluses = pumpTest.NewRandomBolusMap(2, 2) - (*datum.Boluses)[pumpTest.BolusName(1)].AmountMaximum.Units = nil - (*datum.Boluses)[pumpTest.BolusName(2)].Extended.Enabled = nil - (*datum.Boluses)[pumpTest.BolusName(1)].Calculator.Enabled = nil + datum.Boluses = pumpTest.NewRandomBolusMap(1, 1) + for _, v := range *datum.Boluses { + v.AmountMaximum.Units = nil + v.Extended.Enabled = nil + v.Calculator.Enabled = nil + } }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), fmt.Sprintf("/boluses/%s/amountMaximum/units", pumpTest.BolusName(1)), pumpTest.NewMeta()), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), fmt.Sprintf("/boluses/%s/calculator/enabled", pumpTest.BolusName(1)), pumpTest.NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), fmt.Sprintf("/boluses/%s/extended/enabled", pumpTest.BolusName(2)), pumpTest.NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), fmt.Sprintf("/boluses/%s/extended/enabled", pumpTest.BolusName(1)), pumpTest.NewMeta()), ), Entry("boluses valid", pointer.FromString("mmol/L"), @@ -669,12 +671,12 @@ var _ = Describe("Pump", func() { pointer.FromString("mmol/L"), func(datum *pump.Pump, unitsBloodGlucose *string) { datum.SleepSchedules = pumpTest.RandomSleepSchedules(2) - (*datum.SleepSchedules)[pumpTest.SleepScheduleName(0)].End = pointer.FromInt(pump.SleepSchedulesMidnightOffsetMaximum + 1) + (*datum.SleepSchedules)[pumpTest.SleepScheduleName(1)].End = pointer.FromInt(pump.SleepSchedulesMidnightOffsetMaximum + 1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange( pump.SleepSchedulesMidnightOffsetMaximum+1, 0, pump.SleepSchedulesMidnightOffsetMaximum), - fmt.Sprintf("/sleepSchedules/%s/end", pumpTest.SleepScheduleName(0)), pumpTest.NewMeta()), + fmt.Sprintf("/sleepSchedules/%s/end", pumpTest.SleepScheduleName(1)), pumpTest.NewMeta()), ), Entry("sleep schedules valid", pointer.FromString("mmol/L"), From acd4869162ab1961af734b0130e675445dce0727 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 26 Jun 2024 15:28:29 +1200 Subject: [PATCH 308/413] fix nil check --- data/types/common/day_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/data/types/common/day_test.go b/data/types/common/day_test.go index b0d7a96ea0..6752afce1a 100644 --- a/data/types/common/day_test.go +++ b/data/types/common/day_test.go @@ -57,7 +57,11 @@ var _ = Describe("Day", func() { func(day string, expectedIndex int, expectedErr error) { actualIndex, actualError := common.DayIndex(day) Expect(actualIndex).To(Equal(expectedIndex)) - Expect(actualError).To(Equal(expectedErr)) + if expectedErr == nil { + Expect(actualError).To(BeNil()) + } else { + Expect(actualError).To(Equal(expectedErr)) + } }, Entry("is an empty string", "", 0, errors.New("invalid day of the week")), Entry("is sunday", "sunday", 1, nil), From ba2b6646a2accf643046d8e23c28ea743b7796d9 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 27 Jun 2024 12:39:28 +1200 Subject: [PATCH 309/413] simple dataset comparison tool --- .../utils/compare_datasets.go | 88 ++++++++++++ .../utils/compare_datasets_test.go | 46 +++++++ .../utils/data_verify.go | 48 +++++++ .../verify/verify.go | 130 ++++++++++++++++++ 4 files changed, 312 insertions(+) create mode 100644 migrations/20231128_jellyfish_migration/utils/compare_datasets.go create mode 100644 migrations/20231128_jellyfish_migration/utils/compare_datasets_test.go create mode 100644 migrations/20231128_jellyfish_migration/utils/data_verify.go create mode 100644 migrations/20231128_jellyfish_migration/verify/verify.go diff --git a/migrations/20231128_jellyfish_migration/utils/compare_datasets.go b/migrations/20231128_jellyfish_migration/utils/compare_datasets.go new file mode 100644 index 0000000000..880e2752dc --- /dev/null +++ b/migrations/20231128_jellyfish_migration/utils/compare_datasets.go @@ -0,0 +1,88 @@ +package utils + +import ( + "context" + "errors" + "fmt" + "strings" + + "github.com/r3labs/diff/v3" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + +func CompareDatasets(a []map[string]interface{}, b []map[string]interface{}) (map[string]string, error) { + + cleanedA := []map[string]interface{}{} + cleanedB := []map[string]interface{}{} + + doNotCompare := []string{ + "_active", + "_archivedTime", + "_groupId", + "_id", + "id", + "_schemaVersion", + "_userId", + "_version", + "createdTime", + "guid", + "modifiedTime", + "uploadId", + "deduplicator", + "time", + } + + for _, datum := range b { + for _, key := range doNotCompare { + delete(datum, key) + } + cleanedB = append(cleanedB, datum) + } + + for _, datum := range a { + for _, key := range doNotCompare { + delete(datum, key) + } + cleanedA = append(cleanedA, datum) + } + + changelog, err := diff.Diff(cleanedA, cleanedB, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true)) + if err != nil { + return nil, err + } + + differences := map[string]string{} + for _, change := range changelog { + differences[fmt.Sprintf("[%s] %s", change.Type, strings.Join(change.Path, "."))] = fmt.Sprintf("expected:[%v] actual:[%v]", change.From, change.To) + } + return differences, nil +} + +func fetchDataSet(ctx context.Context, dataC *mongo.Collection, uploadID string) ([]map[string]interface{}, error) { + if dataC == nil { + return nil, errors.New("missing data collection") + } + + dataset := []map[string]interface{}{} + + dDataCursor, err := dataC.Find(ctx, bson.M{ + "uploadId": uploadID, + }, &options.FindOptions{ + Sort: bson.M{"time": 1}, + }) + if err != nil { + return nil, err + } + defer dDataCursor.Close(ctx) + + for dDataCursor.Next(ctx) { + var result map[string]interface{} + if err := dDataCursor.Decode(&result); err != nil { + return nil, err + } + dataset = append(dataset, result) + } + return dataset, nil +} diff --git a/migrations/20231128_jellyfish_migration/utils/compare_datasets_test.go b/migrations/20231128_jellyfish_migration/utils/compare_datasets_test.go new file mode 100644 index 0000000000..69460cbd90 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/utils/compare_datasets_test.go @@ -0,0 +1,46 @@ +package utils_test + +import ( + "fmt" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" + "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils/test" +) + +var _ = Describe("CompareDatasets", func() { + + It("will genterate a list of differences between two datasets", func() { + jfDataset := test.BulkJellyfishData("test-device-88x89", "test-group-id", "test-user-id-123", 2) + platformDataset := test.BulkJellyfishData("test-device-88x89", "test-group-id_2", "test-user-id-987", 2) + changes, err := utils.CompareDatasets(jfDataset, platformDataset) + Expect(err).To(BeNil()) + Expect(changes).ToNot(BeEmpty()) + }) + + It("will genterate no differences when the datasets are the same ", func() { + jfDataset := test.BulkJellyfishData("test-device-88x89", "test-group-id", "test-user-id-123", 100) + changes, err := utils.CompareDatasets(jfDataset, jfDataset) + Expect(err).To(BeNil()) + Expect(changes).To(BeEmpty()) + }) + + It("will not compare defined fields", func() { + jfDataset := test.BulkJellyfishData("test-device-88x89", "test-group-id", "test-user-id-123", 10) + + datasetCopy := []map[string]interface{}{} + + for _, datum := range jfDataset { + datum["_groupId"] = fmt.Sprintf("%v_zz2", datum["_groupId"]) + datum["_userId"] = fmt.Sprintf("%v_99y", datum["_userId"]) + datasetCopy = append(datasetCopy, datum) + } + + changes, err := utils.CompareDatasets(jfDataset, datasetCopy) + Expect(err).To(BeNil()) + Expect(changes).To(BeEmpty()) + }) + +}) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go new file mode 100644 index 0000000000..853a838688 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -0,0 +1,48 @@ +package utils + +import ( + "context" + "fmt" + + "go.mongodb.org/mongo-driver/mongo" +) + +type DataVerify struct { + ctx context.Context + dataC *mongo.Collection +} + +func NewVerifier(ctx context.Context, dataC *mongo.Collection) (*DataVerify, error) { + var err error + + if dataC != nil { + return nil, err + } + + m := &DataVerify{ + ctx: ctx, + dataC: dataC, + } + + return m, nil +} + +func (m *DataVerify) Verify(ref string, a string, b string) error { + + datasetA, err := fetchDataSet(m.ctx, m.dataC, a) + if err != nil { + return err + } + + datasetB, err := fetchDataSet(m.ctx, m.dataC, b) + if err != nil { + return err + } + + difference, err := CompareDatasets(datasetA, datasetB) + if err != nil { + return err + } + fmt.Printf("%v", difference) + return nil +} diff --git a/migrations/20231128_jellyfish_migration/verify/verify.go b/migrations/20231128_jellyfish_migration/verify/verify.go new file mode 100644 index 0000000000..30b2cfd7f2 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/verify/verify.go @@ -0,0 +1,130 @@ +package main + +import ( + "context" + "fmt" + "log" + "os" + "strings" + + "github.com/urfave/cli" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + + "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" +) + +type Verify struct { + ctx context.Context + cli *cli.App + config *config + client *mongo.Client + verificationUtil *utils.DataVerify +} + +type config struct { + mongoURI string + ref string + uploadOneID string + uploadTwoID string +} + +const MongoURIFlag = "uri" +const UploadIDOneFlag = "upload-id-one" +const UploadIDTwoFlag = "upload-id-two" +const ReferenceFlag = "reference" + +func main() { + ctx := context.Background() + ctx, cancel := context.WithCancel(ctx) + defer cancel() + verifier := NewVerifier(ctx) + verifier.RunAndExit() + log.Println("finished verification") +} + +func NewVerifier(ctx context.Context) *Verify { + return &Verify{ + config: &config{}, + ctx: ctx, + cli: cli.NewApp(), + } +} + +func (m *Verify) RunAndExit() { + if err := m.Initialize(); err != nil { + os.Exit(1) + } + + m.CLI().Action = func(ctx *cli.Context) error { + + var err error + m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(strings.TrimSpace(m.config.mongoURI))) + if err != nil { + return fmt.Errorf("unable to connect to MongoDB: %w", err) + } + defer m.client.Disconnect(m.ctx) + + m.verificationUtil, err = utils.NewVerifier( + m.ctx, + m.client.Database("data").Collection("deviceData"), + ) + + if err != nil { + return fmt.Errorf("unable to create verification utils : %w", err) + } + + return m.verificationUtil.Verify(m.config.ref, m.config.uploadOneID, m.config.uploadTwoID) + } + + if err := m.CLI().Run(os.Args); err != nil { + if m.client != nil { + m.client.Disconnect(m.ctx) + } + os.Exit(1) + } +} + +func (m *Verify) Initialize() error { + m.CLI().Usage = "dataset verifictaion tool to compare dataset-a with dataset-b" + m.CLI().Authors = []cli.Author{ + { + Name: "J H BATE", + Email: "jamie@tidepool.org", + }, + } + m.CLI().Flags = append(m.CLI().Flags, + cli.StringFlag{ + Name: UploadIDOneFlag, + Usage: "uploadID of the first dataset", + Destination: &m.config.uploadOneID, + Required: true, + }, + cli.StringFlag{ + Name: UploadIDOneFlag, + Usage: "uploadID of the second dataset", + Destination: &m.config.uploadTwoID, + Required: true, + }, + cli.StringFlag{ + Name: ReferenceFlag, + Usage: "comparison reference", + Value: "todo-reference", + Destination: &m.config.ref, + Required: false, + }, + cli.StringFlag{ + Name: MongoURIFlag, + Usage: "mongo connection URI", + Destination: &m.config.mongoURI, + Required: false, + //uri string comes from file called `uri` + FilePath: "./uri", + }, + ) + return nil +} + +func (m *Verify) CLI() *cli.App { + return m.cli +} From 5b4d5807a55128f5d545c55b41815fd6bc0ca385 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 27 Jun 2024 14:48:01 +1200 Subject: [PATCH 310/413] fix flag name --- migrations/20231128_jellyfish_migration/verify/verify.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/verify/verify.go b/migrations/20231128_jellyfish_migration/verify/verify.go index 30b2cfd7f2..56794021da 100644 --- a/migrations/20231128_jellyfish_migration/verify/verify.go +++ b/migrations/20231128_jellyfish_migration/verify/verify.go @@ -101,7 +101,7 @@ func (m *Verify) Initialize() error { Required: true, }, cli.StringFlag{ - Name: UploadIDOneFlag, + Name: UploadIDTwoFlag, Usage: "uploadID of the second dataset", Destination: &m.config.uploadTwoID, Required: true, From 23f946ba782cf2a03c348b9ab8978c00fd7e7e73 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 27 Jun 2024 15:25:26 +1200 Subject: [PATCH 311/413] debug logging --- migrations/20231128_jellyfish_migration/verify/verify.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/verify/verify.go b/migrations/20231128_jellyfish_migration/verify/verify.go index 56794021da..4ab8713546 100644 --- a/migrations/20231128_jellyfish_migration/verify/verify.go +++ b/migrations/20231128_jellyfish_migration/verify/verify.go @@ -53,6 +53,7 @@ func NewVerifier(ctx context.Context) *Verify { func (m *Verify) RunAndExit() { if err := m.Initialize(); err != nil { + log.Printf("error during Initialize [%s]", err.Error()) os.Exit(1) } @@ -81,6 +82,7 @@ func (m *Verify) RunAndExit() { if m.client != nil { m.client.Disconnect(m.ctx) } + log.Printf("error during Run [%s]", err.Error()) os.Exit(1) } } From 2bbde7ca0eaad50c77465f667107d7ad3f2e402b Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 27 Jun 2024 15:46:39 +1200 Subject: [PATCH 312/413] error checking --- .../20231128_jellyfish_migration/utils/data_verify.go | 6 +++--- migrations/20231128_jellyfish_migration/verify/verify.go | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 853a838688..01f7820bd7 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -2,6 +2,7 @@ package utils import ( "context" + "errors" "fmt" "go.mongodb.org/mongo-driver/mongo" @@ -13,10 +14,9 @@ type DataVerify struct { } func NewVerifier(ctx context.Context, dataC *mongo.Collection) (*DataVerify, error) { - var err error - if dataC != nil { - return nil, err + if dataC == nil { + return nil, errors.New("missing required data collection") } m := &DataVerify{ diff --git a/migrations/20231128_jellyfish_migration/verify/verify.go b/migrations/20231128_jellyfish_migration/verify/verify.go index 4ab8713546..8e5909f8b4 100644 --- a/migrations/20231128_jellyfish_migration/verify/verify.go +++ b/migrations/20231128_jellyfish_migration/verify/verify.go @@ -75,7 +75,11 @@ func (m *Verify) RunAndExit() { return fmt.Errorf("unable to create verification utils : %w", err) } - return m.verificationUtil.Verify(m.config.ref, m.config.uploadOneID, m.config.uploadTwoID) + err = m.verificationUtil.Verify(m.config.ref, m.config.uploadOneID, m.config.uploadTwoID) + if err != nil { + log.Printf("error running verify : %s", err.Error()) + } + return nil } if err := m.CLI().Run(os.Args); err != nil { From 2ccdb24286439f0f3960f296245ca0936c02b042 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 27 Jun 2024 16:20:36 +1200 Subject: [PATCH 313/413] logging for diffs --- .../utils/compare_datasets.go | 15 ++++++--------- .../utils/data_verify.go | 5 +++-- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/compare_datasets.go b/migrations/20231128_jellyfish_migration/utils/compare_datasets.go index 880e2752dc..1ffaea8db7 100644 --- a/migrations/20231128_jellyfish_migration/utils/compare_datasets.go +++ b/migrations/20231128_jellyfish_migration/utils/compare_datasets.go @@ -4,12 +4,12 @@ import ( "context" "errors" "fmt" + "log" "strings" "github.com/r3labs/diff/v3" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" ) func CompareDatasets(a []map[string]interface{}, b []map[string]interface{}) (map[string]string, error) { @@ -67,22 +67,19 @@ func fetchDataSet(ctx context.Context, dataC *mongo.Collection, uploadID string) dataset := []map[string]interface{}{} + log.Printf("fetch dataset [%s]", uploadID) + dDataCursor, err := dataC.Find(ctx, bson.M{ "uploadId": uploadID, - }, &options.FindOptions{ - Sort: bson.M{"time": 1}, }) if err != nil { return nil, err } defer dDataCursor.Close(ctx) - for dDataCursor.Next(ctx) { - var result map[string]interface{} - if err := dDataCursor.Decode(&result); err != nil { - return nil, err - } - dataset = append(dataset, result) + if err := dDataCursor.All(ctx, &dataset); err != nil { + return nil, err } + log.Printf("got dataset [%s][%d] results", uploadID, len(dataset)) return dataset, nil } diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 01f7820bd7..ef816d99de 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -3,7 +3,7 @@ package utils import ( "context" "errors" - "fmt" + "log" "go.mongodb.org/mongo-driver/mongo" ) @@ -43,6 +43,7 @@ func (m *DataVerify) Verify(ref string, a string, b string) error { if err != nil { return err } - fmt.Printf("%v", difference) + log.Printf("Difference [%s] vs [%s]", a, b) + log.Printf("%v", difference) return nil } From b6c4ea13e9827944a657c72665289cc5d2913d81 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 27 Jun 2024 16:38:55 +1200 Subject: [PATCH 314/413] dont clean datasets for compare --- .../utils/compare_datasets.go | 62 +++++++++---------- .../utils/data_verify.go | 3 +- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/compare_datasets.go b/migrations/20231128_jellyfish_migration/utils/compare_datasets.go index 1ffaea8db7..89b8b3f6ac 100644 --- a/migrations/20231128_jellyfish_migration/utils/compare_datasets.go +++ b/migrations/20231128_jellyfish_migration/utils/compare_datasets.go @@ -14,41 +14,41 @@ import ( func CompareDatasets(a []map[string]interface{}, b []map[string]interface{}) (map[string]string, error) { - cleanedA := []map[string]interface{}{} - cleanedB := []map[string]interface{}{} + // cleanedA := []map[string]interface{}{} + // cleanedB := []map[string]interface{}{} - doNotCompare := []string{ - "_active", - "_archivedTime", - "_groupId", - "_id", - "id", - "_schemaVersion", - "_userId", - "_version", - "createdTime", - "guid", - "modifiedTime", - "uploadId", - "deduplicator", - "time", - } + // doNotCompare := []string{ + // "_active", + // "_archivedTime", + // "_groupId", + // "_id", + // "id", + // "_schemaVersion", + // "_userId", + // "_version", + // "createdTime", + // "guid", + // "modifiedTime", + // "uploadId", + // "deduplicator", + // "time", + // } - for _, datum := range b { - for _, key := range doNotCompare { - delete(datum, key) - } - cleanedB = append(cleanedB, datum) - } + // for _, datum := range b { + // for _, key := range doNotCompare { + // delete(datum, key) + // } + // cleanedB = append(cleanedB, datum) + // } - for _, datum := range a { - for _, key := range doNotCompare { - delete(datum, key) - } - cleanedA = append(cleanedA, datum) - } + // for _, datum := range a { + // for _, key := range doNotCompare { + // delete(datum, key) + // } + // cleanedA = append(cleanedA, datum) + // } - changelog, err := diff.Diff(cleanedA, cleanedB, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true)) + changelog, err := diff.Diff(a, b, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true)) if err != nil { return nil, err } diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index ef816d99de..cb42cddf6c 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -39,11 +39,12 @@ func (m *DataVerify) Verify(ref string, a string, b string) error { return err } + log.Printf("Compare [%s] vs [%s]", a, b) difference, err := CompareDatasets(datasetA, datasetB) if err != nil { return err } - log.Printf("Difference [%s] vs [%s]", a, b) + log.Println("Difference:") log.Printf("%v", difference) return nil } From 29292167fc33cbb97782d9bc45b20ce73b03e27a Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 27 Jun 2024 16:51:42 +1200 Subject: [PATCH 315/413] differ updates --- .../20231128_jellyfish_migration/utils/compare_datasets.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/compare_datasets.go b/migrations/20231128_jellyfish_migration/utils/compare_datasets.go index 89b8b3f6ac..cdd0e06f26 100644 --- a/migrations/20231128_jellyfish_migration/utils/compare_datasets.go +++ b/migrations/20231128_jellyfish_migration/utils/compare_datasets.go @@ -48,13 +48,16 @@ func CompareDatasets(a []map[string]interface{}, b []map[string]interface{}) (ma // cleanedA = append(cleanedA, datum) // } - changelog, err := diff.Diff(a, b, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true)) + log.Println("start diffing") + changelog, err := diff.Diff(a, b, diff.AllowTypeMismatch(true)) if err != nil { return nil, err } + log.Println("diff created") differences := map[string]string{} for _, change := range changelog { + differences[fmt.Sprintf("[%s] %s", change.Type, strings.Join(change.Path, "."))] = fmt.Sprintf("expected:[%v] actual:[%v]", change.From, change.To) } return differences, nil From aaf274b159c1fc8784c5c6dfa665c1a8ec1f1f99 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 27 Jun 2024 17:05:09 +1200 Subject: [PATCH 316/413] trying other options --- .../20231128_jellyfish_migration/utils/compare_datasets.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/compare_datasets.go b/migrations/20231128_jellyfish_migration/utils/compare_datasets.go index cdd0e06f26..35cbec65db 100644 --- a/migrations/20231128_jellyfish_migration/utils/compare_datasets.go +++ b/migrations/20231128_jellyfish_migration/utils/compare_datasets.go @@ -49,7 +49,7 @@ func CompareDatasets(a []map[string]interface{}, b []map[string]interface{}) (ma // } log.Println("start diffing") - changelog, err := diff.Diff(a, b, diff.AllowTypeMismatch(true)) + changelog, err := diff.Diff(a, b, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) if err != nil { return nil, err } From 51517120f5a7edb3365133192404c663bdff1c92 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 27 Jun 2024 17:13:44 +1200 Subject: [PATCH 317/413] limit --- .../20231128_jellyfish_migration/utils/compare_datasets.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/utils/compare_datasets.go b/migrations/20231128_jellyfish_migration/utils/compare_datasets.go index 35cbec65db..a888e1d5a2 100644 --- a/migrations/20231128_jellyfish_migration/utils/compare_datasets.go +++ b/migrations/20231128_jellyfish_migration/utils/compare_datasets.go @@ -8,8 +8,10 @@ import ( "strings" "github.com/r3labs/diff/v3" + "github.com/tidepool-org/platform/pointer" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" ) func CompareDatasets(a []map[string]interface{}, b []map[string]interface{}) (map[string]string, error) { @@ -74,6 +76,9 @@ func fetchDataSet(ctx context.Context, dataC *mongo.Collection, uploadID string) dDataCursor, err := dataC.Find(ctx, bson.M{ "uploadId": uploadID, + }, &options.FindOptions{ + Sort: bson.M{"time": 1}, + Limit: pointer.FromInt64(100), }) if err != nil { return nil, err From 03778dd8d5f8ad82da7a57d1d48f5c08f527b14e Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 27 Jun 2024 17:24:22 +1200 Subject: [PATCH 318/413] remove cruft from compare datasets --- .../utils/compare_datasets.go | 66 +++++++++---------- .../utils/data_verify.go | 4 +- 2 files changed, 34 insertions(+), 36 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/compare_datasets.go b/migrations/20231128_jellyfish_migration/utils/compare_datasets.go index a888e1d5a2..b90451d7c9 100644 --- a/migrations/20231128_jellyfish_migration/utils/compare_datasets.go +++ b/migrations/20231128_jellyfish_migration/utils/compare_datasets.go @@ -16,42 +16,42 @@ import ( func CompareDatasets(a []map[string]interface{}, b []map[string]interface{}) (map[string]string, error) { - // cleanedA := []map[string]interface{}{} - // cleanedB := []map[string]interface{}{} + cleanedA := []map[string]interface{}{} + cleanedB := []map[string]interface{}{} - // doNotCompare := []string{ - // "_active", - // "_archivedTime", - // "_groupId", - // "_id", - // "id", - // "_schemaVersion", - // "_userId", - // "_version", - // "createdTime", - // "guid", - // "modifiedTime", - // "uploadId", - // "deduplicator", - // "time", - // } + doNotCompare := []string{ + "_active", + "_archivedTime", + "_groupId", + "_id", + "id", + "_schemaVersion", + "_userId", + "_version", + "createdTime", + "guid", + "modifiedTime", + "uploadId", + "deduplicator", + "time", + } - // for _, datum := range b { - // for _, key := range doNotCompare { - // delete(datum, key) - // } - // cleanedB = append(cleanedB, datum) - // } + for _, datum := range b { + for _, key := range doNotCompare { + delete(datum, key) + } + cleanedB = append(cleanedB, datum) + } - // for _, datum := range a { - // for _, key := range doNotCompare { - // delete(datum, key) - // } - // cleanedA = append(cleanedA, datum) - // } + for _, datum := range a { + for _, key := range doNotCompare { + delete(datum, key) + } + cleanedA = append(cleanedA, datum) + } log.Println("start diffing") - changelog, err := diff.Diff(a, b, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) + changelog, err := diff.Diff(cleanedA, cleanedB, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) if err != nil { return nil, err } @@ -59,7 +59,7 @@ func CompareDatasets(a []map[string]interface{}, b []map[string]interface{}) (ma differences := map[string]string{} for _, change := range changelog { - + log.Printf("[%s] %s => expected:[%v] actual:[%v]", change.Type, strings.Join(change.Path, "."), change.From, change.To) differences[fmt.Sprintf("[%s] %s", change.Type, strings.Join(change.Path, "."))] = fmt.Sprintf("expected:[%v] actual:[%v]", change.From, change.To) } return differences, nil @@ -78,7 +78,7 @@ func fetchDataSet(ctx context.Context, dataC *mongo.Collection, uploadID string) "uploadId": uploadID, }, &options.FindOptions{ Sort: bson.M{"time": 1}, - Limit: pointer.FromInt64(100), + Limit: pointer.FromInt64(10), }) if err != nil { return nil, err diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index cb42cddf6c..04f70ba2d7 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -40,11 +40,9 @@ func (m *DataVerify) Verify(ref string, a string, b string) error { } log.Printf("Compare [%s] vs [%s]", a, b) - difference, err := CompareDatasets(datasetA, datasetB) + _, err = CompareDatasets(datasetA, datasetB) if err != nil { return err } - log.Println("Difference:") - log.Printf("%v", difference) return nil } From 7a625c40af2420c50e75f74f1a452e5b26a9c872 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Jul 2024 08:11:51 +1200 Subject: [PATCH 319/413] remove fields not required for comparison --- .../20231128_jellyfish_migration/utils/compare_datasets.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/migrations/20231128_jellyfish_migration/utils/compare_datasets.go b/migrations/20231128_jellyfish_migration/utils/compare_datasets.go index b90451d7c9..fb8e5a5707 100644 --- a/migrations/20231128_jellyfish_migration/utils/compare_datasets.go +++ b/migrations/20231128_jellyfish_migration/utils/compare_datasets.go @@ -33,7 +33,9 @@ func CompareDatasets(a []map[string]interface{}, b []map[string]interface{}) (ma "modifiedTime", "uploadId", "deduplicator", + "_deduplicator", "time", + "provenance", //provenance.byUserID } for _, datum := range b { From 412154a29ed2e0eee7cea4772e7ad8407b08ff56 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Jul 2024 08:48:39 +1200 Subject: [PATCH 320/413] run diff for a dataset in batches --- .../utils/compare_datasets.go | 106 ++++++++++-------- 1 file changed, 61 insertions(+), 45 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/compare_datasets.go b/migrations/20231128_jellyfish_migration/utils/compare_datasets.go index fb8e5a5707..82d7212127 100644 --- a/migrations/20231128_jellyfish_migration/utils/compare_datasets.go +++ b/migrations/20231128_jellyfish_migration/utils/compare_datasets.go @@ -8,63 +8,80 @@ import ( "strings" "github.com/r3labs/diff/v3" - "github.com/tidepool-org/platform/pointer" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) -func CompareDatasets(a []map[string]interface{}, b []map[string]interface{}) (map[string]string, error) { - - cleanedA := []map[string]interface{}{} - cleanedB := []map[string]interface{}{} - - doNotCompare := []string{ - "_active", - "_archivedTime", - "_groupId", - "_id", - "id", - "_schemaVersion", - "_userId", - "_version", - "createdTime", - "guid", - "modifiedTime", - "uploadId", - "deduplicator", - "_deduplicator", - "time", - "provenance", //provenance.byUserID - } +func CompareDatasets(setA []map[string]interface{}, setB []map[string]interface{}) (map[string]string, error) { + + batch := 100 + differences := map[string]string{} + + var processBatch = func(batchA, batchB []map[string]interface{}) error { + + cleanedA := []map[string]interface{}{} + cleanedB := []map[string]interface{}{} - for _, datum := range b { - for _, key := range doNotCompare { - delete(datum, key) + doNotCompare := []string{ + "_active", + "_archivedTime", + "_groupId", + "_id", + "id", + "_schemaVersion", + "_userId", + "_version", + "createdTime", + "guid", + "modifiedTime", + "uploadId", + "deduplicator", + "_deduplicator", + "time", + "provenance", //provenance.byUserID } - cleanedB = append(cleanedB, datum) - } - for _, datum := range a { - for _, key := range doNotCompare { - delete(datum, key) + for _, datum := range batchA { + for _, key := range doNotCompare { + delete(datum, key) + } + cleanedB = append(cleanedB, datum) } - cleanedA = append(cleanedA, datum) - } - log.Println("start diffing") - changelog, err := diff.Diff(cleanedA, cleanedB, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) - if err != nil { - return nil, err + for _, datum := range batchB { + for _, key := range doNotCompare { + delete(datum, key) + } + cleanedA = append(cleanedA, datum) + } + + log.Println("start diffing") + changelog, err := diff.Diff(cleanedA, cleanedB, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) + if err != nil { + return err + } + log.Println("diff created") + + for _, change := range changelog { + log.Printf("[%s] %s => expected:[%v] actual:[%v]", change.Type, strings.Join(change.Path, "."), change.From, change.To) + differences[fmt.Sprintf("[%s] %s", change.Type, strings.Join(change.Path, "."))] = fmt.Sprintf("expected:[%v] actual:[%v]", change.From, change.To) + } + return nil } - log.Println("diff created") - differences := map[string]string{} - for _, change := range changelog { - log.Printf("[%s] %s => expected:[%v] actual:[%v]", change.Type, strings.Join(change.Path, "."), change.From, change.To) - differences[fmt.Sprintf("[%s] %s", change.Type, strings.Join(change.Path, "."))] = fmt.Sprintf("expected:[%v] actual:[%v]", change.From, change.To) + for i := 0; i < len(setA); i += batch { + j := i + batch + if j > len(setA) { + j = len(setA) + } + if err := processBatch(setA[i:j], setB[i:j]); err != nil { + return nil, err + } + } return differences, nil + } func fetchDataSet(ctx context.Context, dataC *mongo.Collection, uploadID string) ([]map[string]interface{}, error) { @@ -79,8 +96,7 @@ func fetchDataSet(ctx context.Context, dataC *mongo.Collection, uploadID string) dDataCursor, err := dataC.Find(ctx, bson.M{ "uploadId": uploadID, }, &options.FindOptions{ - Sort: bson.M{"time": 1}, - Limit: pointer.FromInt64(10), + Sort: bson.M{"time": 1}, }) if err != nil { return nil, err From 3b93bb60350b18e4d52f7825bc4e5fb80b2956a7 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Jul 2024 09:18:22 +1200 Subject: [PATCH 321/413] cleanup reporting --- .../utils/compare_datasets.go | 111 ------------------ .../utils/data_verify.go | 108 ++++++++++++++++- ...e_datasets_test.go => data_verify_test.go} | 0 3 files changed, 105 insertions(+), 114 deletions(-) delete mode 100644 migrations/20231128_jellyfish_migration/utils/compare_datasets.go rename migrations/20231128_jellyfish_migration/utils/{compare_datasets_test.go => data_verify_test.go} (100%) diff --git a/migrations/20231128_jellyfish_migration/utils/compare_datasets.go b/migrations/20231128_jellyfish_migration/utils/compare_datasets.go deleted file mode 100644 index 82d7212127..0000000000 --- a/migrations/20231128_jellyfish_migration/utils/compare_datasets.go +++ /dev/null @@ -1,111 +0,0 @@ -package utils - -import ( - "context" - "errors" - "fmt" - "log" - "strings" - - "github.com/r3labs/diff/v3" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" -) - -func CompareDatasets(setA []map[string]interface{}, setB []map[string]interface{}) (map[string]string, error) { - - batch := 100 - differences := map[string]string{} - - var processBatch = func(batchA, batchB []map[string]interface{}) error { - - cleanedA := []map[string]interface{}{} - cleanedB := []map[string]interface{}{} - - doNotCompare := []string{ - "_active", - "_archivedTime", - "_groupId", - "_id", - "id", - "_schemaVersion", - "_userId", - "_version", - "createdTime", - "guid", - "modifiedTime", - "uploadId", - "deduplicator", - "_deduplicator", - "time", - "provenance", //provenance.byUserID - } - - for _, datum := range batchA { - for _, key := range doNotCompare { - delete(datum, key) - } - cleanedB = append(cleanedB, datum) - } - - for _, datum := range batchB { - for _, key := range doNotCompare { - delete(datum, key) - } - cleanedA = append(cleanedA, datum) - } - - log.Println("start diffing") - changelog, err := diff.Diff(cleanedA, cleanedB, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) - if err != nil { - return err - } - log.Println("diff created") - - for _, change := range changelog { - log.Printf("[%s] %s => expected:[%v] actual:[%v]", change.Type, strings.Join(change.Path, "."), change.From, change.To) - differences[fmt.Sprintf("[%s] %s", change.Type, strings.Join(change.Path, "."))] = fmt.Sprintf("expected:[%v] actual:[%v]", change.From, change.To) - } - return nil - } - - for i := 0; i < len(setA); i += batch { - j := i + batch - if j > len(setA) { - j = len(setA) - } - if err := processBatch(setA[i:j], setB[i:j]); err != nil { - return nil, err - } - - } - return differences, nil - -} - -func fetchDataSet(ctx context.Context, dataC *mongo.Collection, uploadID string) ([]map[string]interface{}, error) { - if dataC == nil { - return nil, errors.New("missing data collection") - } - - dataset := []map[string]interface{}{} - - log.Printf("fetch dataset [%s]", uploadID) - - dDataCursor, err := dataC.Find(ctx, bson.M{ - "uploadId": uploadID, - }, &options.FindOptions{ - Sort: bson.M{"time": 1}, - }) - if err != nil { - return nil, err - } - defer dDataCursor.Close(ctx) - - if err := dDataCursor.All(ctx, &dataset); err != nil { - return nil, err - } - log.Printf("got dataset [%s][%d] results", uploadID, len(dataset)) - return dataset, nil -} diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 04f70ba2d7..72d89bb774 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -3,9 +3,14 @@ package utils import ( "context" "errors" + "fmt" "log" + "strings" + "github.com/r3labs/diff/v3" + "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" ) type DataVerify struct { @@ -13,6 +18,74 @@ type DataVerify struct { dataC *mongo.Collection } +func CompareDatasets(setA []map[string]interface{}, setB []map[string]interface{}) ([]string, error) { + + batch := 100 + differences := []string{} + + var processBatch = func(batchA, batchB []map[string]interface{}) error { + + cleanedA := []map[string]interface{}{} + cleanedB := []map[string]interface{}{} + + doNotCompare := []string{ + "_active", + "_archivedTime", + "_groupId", + "_id", + "id", + "_schemaVersion", + "_userId", + "_version", + "createdTime", + "guid", + "modifiedTime", + "uploadId", + "deduplicator", + "_deduplicator", + "time", + "provenance", //provenance.byUserID + } + + for _, datum := range batchA { + for _, key := range doNotCompare { + delete(datum, key) + } + cleanedB = append(cleanedB, datum) + } + + for _, datum := range batchB { + for _, key := range doNotCompare { + delete(datum, key) + } + cleanedA = append(cleanedA, datum) + } + + changelog, err := diff.Diff(cleanedA, cleanedB, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) + if err != nil { + return err + } + + for _, change := range changelog { + differences = append(differences, fmt.Sprintf("[%s] %s => expected:[%v] actual:[%v]", change.Type, strings.Join(change.Path, "."), change.From, change.To)) + } + return nil + } + + for i := 0; i < len(setA); i += batch { + j := i + batch + if j > len(setA) { + j = len(setA) + } + if err := processBatch(setA[i:j], setB[i:j]); err != nil { + return nil, err + } + + } + return differences, nil + +} + func NewVerifier(ctx context.Context, dataC *mongo.Collection) (*DataVerify, error) { if dataC == nil { @@ -27,22 +100,51 @@ func NewVerifier(ctx context.Context, dataC *mongo.Collection) (*DataVerify, err return m, nil } +func (m *DataVerify) fetchDataSet(uploadID string) ([]map[string]interface{}, error) { + if m.dataC == nil { + return nil, errors.New("missing data collection") + } + + dataset := []map[string]interface{}{} + + dDataCursor, err := m.dataC.Find(m.ctx, bson.M{ + "uploadId": uploadID, + }, &options.FindOptions{ + Sort: bson.M{"time": 1}, + }) + if err != nil { + return nil, err + } + defer dDataCursor.Close(m.ctx) + + if err := dDataCursor.All(m.ctx, &dataset); err != nil { + return nil, err + } + log.Printf("got dataset [%s][%d] results", uploadID, len(dataset)) + return dataset, nil +} + func (m *DataVerify) Verify(ref string, a string, b string) error { - datasetA, err := fetchDataSet(m.ctx, m.dataC, a) + datasetA, err := m.fetchDataSet(a) if err != nil { return err } - datasetB, err := fetchDataSet(m.ctx, m.dataC, b) + datasetB, err := m.fetchDataSet(b) if err != nil { return err } log.Printf("Compare [%s] vs [%s]", a, b) - _, err = CompareDatasets(datasetA, datasetB) + differences, err := CompareDatasets(datasetA, datasetB) if err != nil { return err } + + for _, v := range differences { + log.Println(v) + } + return nil } diff --git a/migrations/20231128_jellyfish_migration/utils/compare_datasets_test.go b/migrations/20231128_jellyfish_migration/utils/data_verify_test.go similarity index 100% rename from migrations/20231128_jellyfish_migration/utils/compare_datasets_test.go rename to migrations/20231128_jellyfish_migration/utils/data_verify_test.go From 7a16063d67378d87abee9839a888d819aea190d9 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Jul 2024 12:40:37 +1200 Subject: [PATCH 322/413] allow finding of blobs --- .../utils/data_verify.go | 64 +++++++++++++------ .../verify/verify.go | 52 +++++++++------ 2 files changed, 76 insertions(+), 40 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 72d89bb774..df4c478e72 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -18,15 +18,15 @@ type DataVerify struct { dataC *mongo.Collection } -func CompareDatasets(setA []map[string]interface{}, setB []map[string]interface{}) ([]string, error) { +func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[string]interface{}) ([]string, error) { batch := 100 differences := []string{} - var processBatch = func(batchA, batchB []map[string]interface{}) error { + var processBatch = func(batchPlatform, batchJellyfish []map[string]interface{}) error { - cleanedA := []map[string]interface{}{} - cleanedB := []map[string]interface{}{} + cleanedJellyfish := []map[string]interface{}{} + cleanedPlatform := []map[string]interface{}{} doNotCompare := []string{ "_active", @@ -43,25 +43,26 @@ func CompareDatasets(setA []map[string]interface{}, setB []map[string]interface{ "uploadId", "deduplicator", "_deduplicator", + "payload", "time", "provenance", //provenance.byUserID } - for _, datum := range batchA { + for _, datum := range batchPlatform { for _, key := range doNotCompare { delete(datum, key) } - cleanedB = append(cleanedB, datum) + cleanedPlatform = append(cleanedPlatform, datum) } - for _, datum := range batchB { + for _, datum := range batchJellyfish { for _, key := range doNotCompare { delete(datum, key) } - cleanedA = append(cleanedA, datum) + cleanedJellyfish = append(cleanedJellyfish, datum) } - changelog, err := diff.Diff(cleanedA, cleanedB, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) + changelog, err := diff.Diff(cleanedPlatform, cleanedJellyfish, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) if err != nil { return err } @@ -72,12 +73,12 @@ func CompareDatasets(setA []map[string]interface{}, setB []map[string]interface{ return nil } - for i := 0; i < len(setA); i += batch { + for i := 0; i < len(platformData); i += batch { j := i + batch - if j > len(setA) { - j = len(setA) + if j > len(platformData) { + j = len(platformData) } - if err := processBatch(setA[i:j], setB[i:j]); err != nil { + if err := processBatch(platformData[i:j], jellyfishData[i:j]); err != nil { return nil, err } @@ -110,7 +111,7 @@ func (m *DataVerify) fetchDataSet(uploadID string) ([]map[string]interface{}, er dDataCursor, err := m.dataC.Find(m.ctx, bson.M{ "uploadId": uploadID, }, &options.FindOptions{ - Sort: bson.M{"time": 1}, + Sort: bson.M{"time": 1, "type": 1}, }) if err != nil { return nil, err @@ -124,20 +125,45 @@ func (m *DataVerify) fetchDataSet(uploadID string) ([]map[string]interface{}, er return dataset, nil } -func (m *DataVerify) Verify(ref string, a string, b string) error { +func (m *DataVerify) FetchBlobIDs() ([]map[string]interface{}, error) { + if m.dataC == nil { + return nil, errors.New("missing data collection") + } + + blobData := []map[string]interface{}{} + + dDataCursor, err := m.dataC.Find(m.ctx, bson.M{ + "deviceManufacturers": bson.M{"$in": []string{"Tandem", "Insulet"}}, + "client.private.blobId": bson.M{"$exists": true}, + }, &options.FindOptions{ + Sort: bson.M{"time": 1}, + Projection: bson.M{"client.private.blobId": 1, "time": 1, "deviceManufacturers": 1}, + }) + if err != nil { + return nil, err + } + defer dDataCursor.Close(m.ctx) + + if err := dDataCursor.All(m.ctx, &blobData); err != nil { + return nil, err + } + return blobData, nil +} + +func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUploadID string) error { - datasetA, err := m.fetchDataSet(a) + platformDataset, err := m.fetchDataSet(platformUploadID) if err != nil { return err } - datasetB, err := m.fetchDataSet(b) + jellyfishDataset, err := m.fetchDataSet(jellyfishUploadID) if err != nil { return err } - log.Printf("Compare [%s] vs [%s]", a, b) - differences, err := CompareDatasets(datasetA, datasetB) + log.Printf("Compare platform[%s] vs jellyfish[%s]", platformUploadID, jellyfishUploadID) + differences, err := CompareDatasets(platformDataset, jellyfishDataset) if err != nil { return err } diff --git a/migrations/20231128_jellyfish_migration/verify/verify.go b/migrations/20231128_jellyfish_migration/verify/verify.go index 8e5909f8b4..5b88faa3be 100644 --- a/migrations/20231128_jellyfish_migration/verify/verify.go +++ b/migrations/20231128_jellyfish_migration/verify/verify.go @@ -23,16 +23,16 @@ type Verify struct { } type config struct { - mongoURI string - ref string - uploadOneID string - uploadTwoID string + mongoURI string + findBlobs bool + platformUploadID string + jellyfishUploadID string } const MongoURIFlag = "uri" -const UploadIDOneFlag = "upload-id-one" -const UploadIDTwoFlag = "upload-id-two" -const ReferenceFlag = "reference" +const PlatformUploadIDFlag = "upload-id-platform" +const JellyfishUploadIDFlag = "upload-id-jellyfish" +const FindBlobFlag = "find-blobs" func main() { ctx := context.Background() @@ -66,6 +66,17 @@ func (m *Verify) RunAndExit() { } defer m.client.Disconnect(m.ctx) + if m.config.findBlobs { + if ids, err := m.verificationUtil.FetchBlobIDs(); err != nil { + return err + } else { + for i, v := range ids { + log.Printf("%d - %v", i, v) + } + } + return nil + } + m.verificationUtil, err = utils.NewVerifier( m.ctx, m.client.Database("data").Collection("deviceData"), @@ -75,7 +86,7 @@ func (m *Verify) RunAndExit() { return fmt.Errorf("unable to create verification utils : %w", err) } - err = m.verificationUtil.Verify(m.config.ref, m.config.uploadOneID, m.config.uploadTwoID) + err = m.verificationUtil.Verify("ref", m.config.platformUploadID, m.config.jellyfishUploadID) if err != nil { log.Printf("error running verify : %s", err.Error()) } @@ -101,22 +112,21 @@ func (m *Verify) Initialize() error { } m.CLI().Flags = append(m.CLI().Flags, cli.StringFlag{ - Name: UploadIDOneFlag, - Usage: "uploadID of the first dataset", - Destination: &m.config.uploadOneID, - Required: true, + Name: PlatformUploadIDFlag, + Usage: "uploadID of the first platform dataset", + Destination: &m.config.platformUploadID, + Required: false, }, cli.StringFlag{ - Name: UploadIDTwoFlag, - Usage: "uploadID of the second dataset", - Destination: &m.config.uploadTwoID, - Required: true, + Name: JellyfishUploadIDFlag, + Usage: "uploadID of the second jellyfish dataset", + Destination: &m.config.jellyfishUploadID, + Required: false, }, - cli.StringFlag{ - Name: ReferenceFlag, - Usage: "comparison reference", - Value: "todo-reference", - Destination: &m.config.ref, + cli.BoolFlag{ + Name: FindBlobFlag, + Usage: "find all blobs for running data verifcation with", + Destination: &m.config.findBlobs, Required: false, }, cli.StringFlag{ From 1991df49ddf19ddd9996a4ae63e32c6da9fea1fc Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Jul 2024 13:04:42 +1200 Subject: [PATCH 323/413] update sort --- migrations/20231128_jellyfish_migration/utils/data_verify.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index df4c478e72..19d397093b 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -111,7 +111,7 @@ func (m *DataVerify) fetchDataSet(uploadID string) ([]map[string]interface{}, er dDataCursor, err := m.dataC.Find(m.ctx, bson.M{ "uploadId": uploadID, }, &options.FindOptions{ - Sort: bson.M{"time": 1, "type": 1}, + Sort: bson.D{{Key: "time", Value: 1}, {Key: "type", Value: -1}}, }) if err != nil { return nil, err From 0886a7cd5e1d0377a41daaa65e1cd60a52838a03 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Jul 2024 13:26:46 +1200 Subject: [PATCH 324/413] group data by type --- .../utils/data_verify.go | 55 ++++++++++++------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 19d397093b..b3aaa665a2 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -101,28 +101,37 @@ func NewVerifier(ctx context.Context, dataC *mongo.Collection) (*DataVerify, err return m, nil } -func (m *DataVerify) fetchDataSet(uploadID string) ([]map[string]interface{}, error) { +func (m *DataVerify) fetchDataSet(uploadID string) (map[string][]map[string]interface{}, error) { if m.dataC == nil { return nil, errors.New("missing data collection") } - dataset := []map[string]interface{}{} + dataTypes := []string{"cbg", "basal", "bolus", "deviceEvent", "wizard", "pumpSettings"} - dDataCursor, err := m.dataC.Find(m.ctx, bson.M{ - "uploadId": uploadID, - }, &options.FindOptions{ - Sort: bson.D{{Key: "time", Value: 1}, {Key: "type", Value: -1}}, - }) - if err != nil { - return nil, err - } - defer dDataCursor.Close(m.ctx) + typeSet := map[string][]map[string]interface{}{} - if err := dDataCursor.All(m.ctx, &dataset); err != nil { - return nil, err + for _, dType := range dataTypes { + + dset := []map[string]interface{}{} + + dDataCursor, err := m.dataC.Find(m.ctx, bson.M{ + "uploadId": uploadID, + "type": dType, + }, &options.FindOptions{ + Sort: bson.M{"time": 1}, + }) + if err != nil { + return nil, err + } + defer dDataCursor.Close(m.ctx) + + if err := dDataCursor.All(m.ctx, &dset); err != nil { + return nil, err + } + log.Printf("got dataset [%s][%s][%d] results", uploadID, dType, len(dset)) + typeSet[dType] = dset } - log.Printf("got dataset [%s][%d] results", uploadID, len(dataset)) - return dataset, nil + return typeSet, nil } func (m *DataVerify) FetchBlobIDs() ([]map[string]interface{}, error) { @@ -163,13 +172,17 @@ func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUpload } log.Printf("Compare platform[%s] vs jellyfish[%s]", platformUploadID, jellyfishUploadID) - differences, err := CompareDatasets(platformDataset, jellyfishDataset) - if err != nil { - return err - } - for _, v := range differences { - log.Println(v) + for dType, jfSet := range jellyfishDataset { + + differences, err := CompareDatasets(platformDataset[dType], jfSet) + if err != nil { + return err + } + + for _, v := range differences { + log.Println(v) + } } return nil From 5d756291878a17985a116e7296ba4c7fddc5ad4e Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Jul 2024 13:27:57 +1200 Subject: [PATCH 325/413] report type --- migrations/20231128_jellyfish_migration/utils/data_verify.go | 1 + 1 file changed, 1 insertion(+) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index b3aaa665a2..fe4c159f72 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -180,6 +180,7 @@ func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUpload return err } + log.Println("TYPE: ", dType) for _, v := range differences { log.Println(v) } From 72521ae291ba79da59208efa2d25b30083f7ec7f Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Jul 2024 14:08:01 +1200 Subject: [PATCH 326/413] allow to pass datatype of upload to compare --- .../utils/data_verify.go | 20 ++++++++++--------- .../verify/verify.go | 11 +++++++++- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index fe4c159f72..84cf61dc8c 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -101,13 +101,13 @@ func NewVerifier(ctx context.Context, dataC *mongo.Collection) (*DataVerify, err return m, nil } -func (m *DataVerify) fetchDataSet(uploadID string) (map[string][]map[string]interface{}, error) { +var DatasetTypes = []string{"cbg", "basal", "bolus", "deviceEvent", "wizard", "pumpSettings"} + +func (m *DataVerify) fetchDataSet(uploadID string, dataTypes []string) (map[string][]map[string]interface{}, error) { if m.dataC == nil { return nil, errors.New("missing data collection") } - dataTypes := []string{"cbg", "basal", "bolus", "deviceEvent", "wizard", "pumpSettings"} - typeSet := map[string][]map[string]interface{}{} for _, dType := range dataTypes { @@ -159,14 +159,18 @@ func (m *DataVerify) FetchBlobIDs() ([]map[string]interface{}, error) { return blobData, nil } -func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUploadID string) error { +func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUploadID string, dataTyes []string) error { - platformDataset, err := m.fetchDataSet(platformUploadID) + if len(dataTyes) == 0 { + dataTyes = DatasetTypes + } + + platformDataset, err := m.fetchDataSet(platformUploadID, dataTyes) if err != nil { return err } - jellyfishDataset, err := m.fetchDataSet(jellyfishUploadID) + jellyfishDataset, err := m.fetchDataSet(jellyfishUploadID, dataTyes) if err != nil { return err } @@ -179,10 +183,8 @@ func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUpload if err != nil { return err } - - log.Println("TYPE: ", dType) for _, v := range differences { - log.Println(v) + log.Printf("%s: %s", strings.ToUpper(dType), v) } } diff --git a/migrations/20231128_jellyfish_migration/verify/verify.go b/migrations/20231128_jellyfish_migration/verify/verify.go index 5b88faa3be..219912eac6 100644 --- a/migrations/20231128_jellyfish_migration/verify/verify.go +++ b/migrations/20231128_jellyfish_migration/verify/verify.go @@ -27,12 +27,14 @@ type config struct { findBlobs bool platformUploadID string jellyfishUploadID string + dataTypes string } const MongoURIFlag = "uri" const PlatformUploadIDFlag = "upload-id-platform" const JellyfishUploadIDFlag = "upload-id-jellyfish" const FindBlobFlag = "find-blobs" +const DataTypesFlag = "data-types" func main() { ctx := context.Background() @@ -86,7 +88,7 @@ func (m *Verify) RunAndExit() { return fmt.Errorf("unable to create verification utils : %w", err) } - err = m.verificationUtil.Verify("ref", m.config.platformUploadID, m.config.jellyfishUploadID) + err = m.verificationUtil.Verify("ref", m.config.platformUploadID, m.config.jellyfishUploadID, strings.Split(m.config.dataTypes, ",")) if err != nil { log.Printf("error running verify : %s", err.Error()) } @@ -123,6 +125,13 @@ func (m *Verify) Initialize() error { Destination: &m.config.jellyfishUploadID, Required: false, }, + cli.StringFlag{ + Name: DataTypesFlag, + Usage: "comma seperated list of data types to compare", + Destination: &m.config.dataTypes, + Required: false, + Value: strings.Join(utils.DatasetTypes, ","), + }, cli.BoolFlag{ Name: FindBlobFlag, Usage: "find all blobs for running data verifcation with", From 54583a03dc38c525beb9fdbc2b9b9ac07090bdb0 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Jul 2024 14:24:59 +1200 Subject: [PATCH 327/413] clean out revision form compare --- .../utils/data_verify.go | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 84cf61dc8c..1ad46ff108 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -31,21 +31,22 @@ func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[ doNotCompare := []string{ "_active", "_archivedTime", + "createdTime", + "deduplicator", + "_deduplicator", "_groupId", + "guid", "_id", "id", - "_schemaVersion", - "_userId", - "_version", - "createdTime", - "guid", "modifiedTime", - "uploadId", - "deduplicator", - "_deduplicator", "payload", + "provenance", + "revision", + "_schemaVersion", "time", - "provenance", //provenance.byUserID + "_userId", + "uploadId", + "_version", } for _, datum := range batchPlatform { From 6a74788d8df52ec3f4367bfc7a2fe3afb702cd14 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Jul 2024 15:31:54 +1200 Subject: [PATCH 328/413] look at 4 smaller batches to compare --- .../utils/data_verify.go | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 1ad46ff108..c299e9329d 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -20,7 +20,20 @@ type DataVerify struct { func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[string]interface{}) ([]string, error) { - batch := 100 + if len(platformData) != len(jellyfishData) { + return nil, fmt.Errorf("datasets mismatch platform (%d) vs jellyfish (%d)", len(platformData), len(jellyfishData)) + } + + quater := len(platformData) / 4 + + batchStarts := []int{ + 0, + quater, + quater * 2, + quater * 3, + } + + batch := 20 differences := []string{} var processBatch = func(batchPlatform, batchJellyfish []map[string]interface{}) error { @@ -74,16 +87,28 @@ func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[ return nil } - for i := 0; i < len(platformData); i += batch { - j := i + batch + for _, startAt := range batchStarts { + j := startAt + batch + if j > len(platformData) { j = len(platformData) } - if err := processBatch(platformData[i:j], jellyfishData[i:j]); err != nil { + if err := processBatch(platformData[startAt:j], jellyfishData[startAt:j]); err != nil { return nil, err } } + + // for i := 0; i < len(platformData); i += batch { + // j := i + batch + // if j > len(platformData) { + // j = len(platformData) + // } + // if err := processBatch(platformData[i:j], jellyfishData[i:j]); err != nil { + // return nil, err + // } + + // } return differences, nil } From 14d9ee878db54c652b2645463043f51c5acb1818 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Jul 2024 16:27:31 +1200 Subject: [PATCH 329/413] depending on amount of data process a subset or all data points --- .../utils/data_verify.go | 80 +++++++++++-------- 1 file changed, 45 insertions(+), 35 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index c299e9329d..fa74cec84b 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -21,22 +21,11 @@ type DataVerify struct { func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[string]interface{}) ([]string, error) { if len(platformData) != len(jellyfishData) { - return nil, fmt.Errorf("datasets mismatch platform (%d) vs jellyfish (%d)", len(platformData), len(jellyfishData)) + log.Printf("NOTE: datasets mismatch platform (%d) vs jellyfish (%d)", len(platformData), len(jellyfishData)) } - quater := len(platformData) / 4 - - batchStarts := []int{ - 0, - quater, - quater * 2, - quater * 3, - } - - batch := 20 - differences := []string{} - - var processBatch = func(batchPlatform, batchJellyfish []map[string]interface{}) error { + // small batches or the diff takes to long + var processBatch = func(diffs []string, batchPlatform, batchJellyfish []map[string]interface{}) error { cleanedJellyfish := []map[string]interface{}{} cleanedPlatform := []map[string]interface{}{} @@ -80,37 +69,58 @@ func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[ if err != nil { return err } - for _, change := range changelog { - differences = append(differences, fmt.Sprintf("[%s] %s => expected:[%v] actual:[%v]", change.Type, strings.Join(change.Path, "."), change.From, change.To)) + diffs = append(diffs, fmt.Sprintf("%s => platform:[%v] jellyfish:[%v]", strings.Join(change.Path, "."), change.From, change.To)) } return nil } - for _, startAt := range batchStarts { - j := startAt + batch - - if j > len(platformData) { - j = len(platformData) + var processAllData = func() ([]string, error) { + batch := 100 + differences := []string{} + for i := 0; i < len(platformData); i += batch { + j := i + batch + if j > len(platformData) { + j = len(platformData) + } + if err := processBatch(differences, platformData[i:j], jellyfishData[i:j]); err != nil { + return nil, err + } } - if err := processBatch(platformData[startAt:j], jellyfishData[startAt:j]); err != nil { - return nil, err + return differences, nil + } + + var processSubsetOfData = func() ([]string, error) { + + differences := []string{} + batch := 20 + quater := len(platformData) / 4 + batchStarts := []int{ + 0, + quater, + quater * 2, + quater * 3, } - } + log.Printf("NOTE: comparing a subset of all [%d] datum with a batch size [%d] starting at [%v] ", len(platformData), batch, batchStarts) - // for i := 0; i < len(platformData); i += batch { - // j := i + batch - // if j > len(platformData) { - // j = len(platformData) - // } - // if err := processBatch(platformData[i:j], jellyfishData[i:j]); err != nil { - // return nil, err - // } + for _, startAt := range batchStarts { + j := startAt + batch - // } - return differences, nil + if j > len(platformData) { + j = len(platformData) + } + if err := processBatch(differences, platformData[startAt:j], jellyfishData[startAt:j]); err != nil { + return nil, err + } + } + return differences, nil + } + if len(platformData) <= 100 { + return processAllData() + } + return processSubsetOfData() } func NewVerifier(ctx context.Context, dataC *mongo.Collection) (*DataVerify, error) { @@ -210,7 +220,7 @@ func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUpload return err } for _, v := range differences { - log.Printf("%s: %s", strings.ToUpper(dType), v) + log.Printf("%s.%s", dType, v) } } From 46a84dc86efe6cea61827f07fe7bc89925be6096 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Jul 2024 16:38:03 +1200 Subject: [PATCH 330/413] batch diffs --- .../utils/data_verify.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index fa74cec84b..066cd89d30 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -25,7 +25,7 @@ func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[ } // small batches or the diff takes to long - var processBatch = func(diffs []string, batchPlatform, batchJellyfish []map[string]interface{}) error { + var processBatch = func(batchPlatform, batchJellyfish []map[string]interface{}) ([]string, error) { cleanedJellyfish := []map[string]interface{}{} cleanedPlatform := []map[string]interface{}{} @@ -67,12 +67,13 @@ func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[ changelog, err := diff.Diff(cleanedPlatform, cleanedJellyfish, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) if err != nil { - return err + return nil, err } + diffs := []string{} for _, change := range changelog { diffs = append(diffs, fmt.Sprintf("%s => platform:[%v] jellyfish:[%v]", strings.Join(change.Path, "."), change.From, change.To)) } - return nil + return diffs, nil } var processAllData = func() ([]string, error) { @@ -83,8 +84,10 @@ func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[ if j > len(platformData) { j = len(platformData) } - if err := processBatch(differences, platformData[i:j], jellyfishData[i:j]); err != nil { + if batchDiff, err := processBatch(platformData[i:j], jellyfishData[i:j]); err != nil { return nil, err + } else { + differences = append(differences, batchDiff...) } } return differences, nil @@ -110,8 +113,10 @@ func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[ if j > len(platformData) { j = len(platformData) } - if err := processBatch(differences, platformData[startAt:j], jellyfishData[startAt:j]); err != nil { + if batchDiff, err := processBatch(platformData[startAt:j], jellyfishData[startAt:j]); err != nil { return nil, err + } else { + differences = append(differences, batchDiff...) } } return differences, nil From ae8d571ebca4ae96647fd63804cfd82cabc2ba5b Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Jul 2024 18:27:13 +1200 Subject: [PATCH 331/413] fix for fetching blob ids --- .../verify/verify.go | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/verify/verify.go b/migrations/20231128_jellyfish_migration/verify/verify.go index 219912eac6..cfb30b0ead 100644 --- a/migrations/20231128_jellyfish_migration/verify/verify.go +++ b/migrations/20231128_jellyfish_migration/verify/verify.go @@ -42,7 +42,6 @@ func main() { defer cancel() verifier := NewVerifier(ctx) verifier.RunAndExit() - log.Println("finished verification") } func NewVerifier(ctx context.Context) *Verify { @@ -69,13 +68,24 @@ func (m *Verify) RunAndExit() { defer m.client.Disconnect(m.ctx) if m.config.findBlobs { - if ids, err := m.verificationUtil.FetchBlobIDs(); err != nil { + m.verificationUtil, err = utils.NewVerifier( + m.ctx, + m.client.Database("data").Collection("deviceDataSets"), + ) + + if err != nil { + return fmt.Errorf("unable to create verification utils : %w", err) + } + + ids, err := m.verificationUtil.FetchBlobIDs() + if err != nil { return err - } else { - for i, v := range ids { - log.Printf("%d - %v", i, v) - } } + log.Println("BLOBS:") + for i, v := range ids { + log.Printf("%d - %v", i, v) + } + return nil } From 75c5cab448ab83d68920dded954598234f0004c6 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Jul 2024 18:54:53 +1200 Subject: [PATCH 332/413] include deviceId with blob details --- migrations/20231128_jellyfish_migration/utils/data_verify.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 066cd89d30..a413a6ce21 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -186,8 +186,8 @@ func (m *DataVerify) FetchBlobIDs() ([]map[string]interface{}, error) { "deviceManufacturers": bson.M{"$in": []string{"Tandem", "Insulet"}}, "client.private.blobId": bson.M{"$exists": true}, }, &options.FindOptions{ - Sort: bson.M{"time": 1}, - Projection: bson.M{"client.private.blobId": 1, "time": 1, "deviceManufacturers": 1}, + Sort: bson.D{{"deviceId", 1}, {"time", 1}}, + Projection: bson.M{"_id": 0, "deviceId": 1, "deviceManufacturers": 1, "client.private.blobId": 1}, }) if err != nil { return nil, err From dd87ea2f48aecb3ec4eaf11a1cf5dbadf7369fb3 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Jul 2024 19:02:47 +1200 Subject: [PATCH 333/413] rename blobId --- migrations/20231128_jellyfish_migration/utils/data_verify.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index a413a6ce21..5d5aedda03 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -187,7 +187,7 @@ func (m *DataVerify) FetchBlobIDs() ([]map[string]interface{}, error) { "client.private.blobId": bson.M{"$exists": true}, }, &options.FindOptions{ Sort: bson.D{{"deviceId", 1}, {"time", 1}}, - Projection: bson.M{"_id": 0, "deviceId": 1, "deviceManufacturers": 1, "client.private.blobId": 1}, + Projection: bson.M{"_id": 0, "deviceId": 1, "blobId": "$client.private.blobId"}, }) if err != nil { return nil, err From 1ed373e467d941723d7611ff5e8bd98eea8a6d69 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 3 Jul 2024 10:02:36 +1200 Subject: [PATCH 334/413] include bolus deliveryContext --- data/types/bolus/bolus.go | 16 +++++++++++++++- data/types/bolus/bolus_test.go | 11 +++++++++++ data/types/bolus/test/bolus.go | 11 +++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/data/types/bolus/bolus.go b/data/types/bolus/bolus.go index 99a6b83e56..3a13b20dc2 100644 --- a/data/types/bolus/bolus.go +++ b/data/types/bolus/bolus.go @@ -10,6 +10,11 @@ import ( const ( Type = "bolus" + + DeliveryContextDevice = "device" + DeliveryContextAlgorithm = "algorithm" + DeliveryContextRemote = "remote" + DeliveryContextUndetermined = "undetermined" ) type Bolus struct { @@ -17,6 +22,7 @@ type Bolus struct { SubType string `json:"subType,omitempty" bson:"subType,omitempty"` + DeliveryContext *string `json:"deliveryContext,omitempty" bson:"deliveryContext,omitempty"` InsulinFormulation *insulin.Formulation `json:"insulinFormulation,omitempty" bson:"insulinFormulation,omitempty"` } @@ -25,6 +31,10 @@ type Meta struct { SubType string `json:"subType,omitempty"` } +func DeliveryContext() []string { + return []string{DeliveryContextDevice, DeliveryContextAlgorithm, DeliveryContextRemote, DeliveryContextUndetermined} +} + func New(subType string) Bolus { return Bolus{ Base: types.New(Type), @@ -41,7 +51,7 @@ func (b *Bolus) Meta() interface{} { func (b *Bolus) Parse(parser structure.ObjectParser) { b.Base.Parse(parser) - + b.DeliveryContext = parser.String("deliveryContext") b.InsulinFormulation = insulin.ParseFormulation(parser.WithReferenceObjectParser("insulinFormulation")) } @@ -57,6 +67,10 @@ func (b *Bolus) Validate(validator structure.Validator) { if b.InsulinFormulation != nil { b.InsulinFormulation.Validate(validator.WithReference("insulinFormulation")) } + + if b.DeliveryContext != nil { + validator.String("deliveryContext", b.DeliveryContext).Exists().OneOf(DeliveryContext()...) + } } func (b *Bolus) Normalize(normalizer data.Normalizer) { diff --git a/data/types/bolus/bolus_test.go b/data/types/bolus/bolus_test.go index 61d98d12f1..1f31e9ac9f 100644 --- a/data/types/bolus/bolus_test.go +++ b/data/types/bolus/bolus_test.go @@ -32,6 +32,7 @@ var _ = Describe("Bolus", func() { Expect(datum.Type).To(Equal("bolus")) Expect(datum.SubType).To(Equal(subType)) Expect(datum.InsulinFormulation).To(BeNil()) + Expect(datum.DeliveryContext).To(BeNil()) }) }) @@ -84,6 +85,16 @@ var _ = Describe("Bolus", func() { Entry("sub type valid", func(datum *bolus.Bolus) { datum.SubType = dataTypesTest.NewType() }, ), + Entry("delivery context missing", + func(datum *bolus.Bolus) { datum.DeliveryContext = nil }, + ), + Entry("delivery context invalid", + func(datum *bolus.Bolus) { datum.DeliveryContext = pointer.FromString("invalid") }, + errorsTest.WithPointerSource(structureValidator.ErrorValueStringNotOneOf("invalid", bolus.DeliveryContext()), "/deliveryContext"), + ), + Entry("delivery context valid", + func(datum *bolus.Bolus) { datum.DeliveryContext = pointer.FromString(bolus.DeliveryContextAlgorithm) }, + ), Entry("insulin formulation missing", func(datum *bolus.Bolus) { datum.InsulinFormulation = nil }, ), diff --git a/data/types/bolus/test/bolus.go b/data/types/bolus/test/bolus.go index b98566a644..9350067681 100644 --- a/data/types/bolus/test/bolus.go +++ b/data/types/bolus/test/bolus.go @@ -4,6 +4,7 @@ import ( dataTypesBolus "github.com/tidepool-org/platform/data/types/bolus" dataTypesInsulinTest "github.com/tidepool-org/platform/data/types/insulin/test" dataTypesTest "github.com/tidepool-org/platform/data/types/test" + "github.com/tidepool-org/platform/pointer" "github.com/tidepool-org/platform/test" ) @@ -11,6 +12,7 @@ func RandomBolus() *dataTypesBolus.Bolus { datum := randomBolus() datum.Base = *dataTypesTest.RandomBase() datum.Type = "bolus" + return datum } @@ -25,9 +27,14 @@ func randomBolus() *dataTypesBolus.Bolus { datum := &dataTypesBolus.Bolus{} datum.SubType = dataTypesTest.NewType() datum.InsulinFormulation = dataTypesInsulinTest.RandomFormulation(3) + datum.DeliveryContext = randomDeliveryContext() return datum } +func randomDeliveryContext() *string { + return pointer.FromString(test.RandomStringFromArray(dataTypesBolus.DeliveryContext())) +} + func CloneBolus(datum *dataTypesBolus.Bolus) *dataTypesBolus.Bolus { if datum == nil { return nil @@ -36,6 +43,7 @@ func CloneBolus(datum *dataTypesBolus.Bolus) *dataTypesBolus.Bolus { clone.Base = *dataTypesTest.CloneBase(&datum.Base) clone.SubType = datum.SubType clone.InsulinFormulation = dataTypesInsulinTest.CloneFormulation(datum.InsulinFormulation) + clone.DeliveryContext = pointer.CloneString(datum.DeliveryContext) return clone } @@ -48,5 +56,8 @@ func NewObjectFromBolus(datum *dataTypesBolus.Bolus, objectFormat test.ObjectFor if datum.InsulinFormulation != nil { object["insulinFormulation"] = dataTypesInsulinTest.NewObjectFromFormulation(datum.InsulinFormulation, objectFormat) } + if datum.DeliveryContext != nil { + object["deliveryContext"] = test.NewObjectFromString(*datum.DeliveryContext, objectFormat) + } return object } From d4e573c41a53225b9e3df7dcff221312c0a6721a Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 3 Jul 2024 10:10:30 +1200 Subject: [PATCH 335/413] add field keys --- migrations/20231128_jellyfish_migration/utils/data_verify.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 5d5aedda03..4ffbb78580 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -186,7 +186,7 @@ func (m *DataVerify) FetchBlobIDs() ([]map[string]interface{}, error) { "deviceManufacturers": bson.M{"$in": []string{"Tandem", "Insulet"}}, "client.private.blobId": bson.M{"$exists": true}, }, &options.FindOptions{ - Sort: bson.D{{"deviceId", 1}, {"time", 1}}, + Sort: bson.D{{Key: "deviceId", Value: 1}, {Key: "time", Value: 1}}, Projection: bson.M{"_id": 0, "deviceId": 1, "blobId": "$client.private.blobId"}, }) if err != nil { From c3725de6856de67f398552503d14c67ce29abd59 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 3 Jul 2024 20:13:50 +1200 Subject: [PATCH 336/413] allow day of week to be case insensitive --- data/types/common/day.go | 28 +++++++++++++++++++++- data/types/settings/cgm/scheduled_alert.go | 2 +- data/types/settings/pump/sleep_schedule.go | 2 +- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/data/types/common/day.go b/data/types/common/day.go index ba82854449..80556f73a7 100644 --- a/data/types/common/day.go +++ b/data/types/common/day.go @@ -1,6 +1,15 @@ package common -import "errors" +import ( + "errors" + "slices" + "strings" + + "github.com/tidepool-org/platform/structure" + "github.com/tidepool-org/platform/structure/validator" + + platformErrors "github.com/tidepool-org/platform/errors" +) const ( DaySunday = "sunday" @@ -65,3 +74,20 @@ func DayIndex(day string) (int, error) { return 0, errors.New("invalid day of the week") } } + +func ErrorValueStringDayNotValid(value string) error { + return platformErrors.Preparedf(validator.ErrorCodeValueNotValid, "value is not valid", "value %q is not valid as a day of the week", value) +} + +func ValidateDayOfWeek(value string) error { + if value == "" { + return validator.ErrorValueEmpty() + } else if !slices.Contains(DaysOfWeek(), strings.ToLower(value)) { + return ErrorValueStringDayNotValid(value) + } + return nil +} + +func DayOfWeekValidator(value string, errorReporter structure.ErrorReporter) { + errorReporter.ReportError(ValidateDayOfWeek(value)) +} diff --git a/data/types/settings/cgm/scheduled_alert.go b/data/types/settings/cgm/scheduled_alert.go index ac9eb59e5c..782ce60e04 100644 --- a/data/types/settings/cgm/scheduled_alert.go +++ b/data/types/settings/cgm/scheduled_alert.go @@ -88,7 +88,7 @@ func (s *ScheduledAlert) Parse(parser structure.ObjectParser) { func (s *ScheduledAlert) Validate(validator structure.Validator) { validator.String("name", s.Name).NotEmpty().LengthLessThanOrEqualTo(ScheduledAlertNameLengthMaximum) - validator.StringArray("days", s.Days).Exists().EachOneOf(dataTypesCommon.DaysOfWeek()...).EachUnique() + validator.StringArray("days", s.Days).Exists().EachUsing(dataTypesCommon.DayOfWeekValidator).EachUnique() validator.Int("start", s.Start).Exists().InRange(ScheduledAlertStartMinimum, ScheduledAlertStartMaximum) validator.Int("end", s.End).Exists().InRange(ScheduledAlertEndMinimum, ScheduledAlertEndMaximum) if alertsValidator := validator.WithReference("alerts"); s.Alerts != nil { diff --git a/data/types/settings/pump/sleep_schedule.go b/data/types/settings/pump/sleep_schedule.go index e1854bcfbc..11a9cd0c39 100644 --- a/data/types/settings/pump/sleep_schedule.go +++ b/data/types/settings/pump/sleep_schedule.go @@ -106,7 +106,7 @@ func (s *SleepSchedule) Validate(validator structure.Validator) { validator.Bool("enabled", s.Enabled).Exists() if s.Enabled != nil { if *s.Enabled { - validator.StringArray("days", s.Days).Exists().EachOneOf(dataTypesCommon.DaysOfWeek()...).EachUnique() + validator.StringArray("days", s.Days).Exists().EachUsing(dataTypesCommon.DayOfWeekValidator).EachUnique() validator.Int("start", s.Start).Exists().InRange(SleepSchedulesMidnightOffsetMinimum, SleepSchedulesMidnightOffsetMaximum) validator.Int("end", s.End).Exists().InRange(SleepSchedulesMidnightOffsetMinimum, SleepSchedulesMidnightOffsetMaximum) } From 0ab37ed752bed48a5af86d2a678b46d69359e9fe Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 4 Jul 2024 08:40:12 +1200 Subject: [PATCH 337/413] test for day of week validation --- data/types/common/day.go | 8 +------- data/types/common/day_test.go | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/data/types/common/day.go b/data/types/common/day.go index 80556f73a7..6546694cd6 100644 --- a/data/types/common/day.go +++ b/data/types/common/day.go @@ -7,8 +7,6 @@ import ( "github.com/tidepool-org/platform/structure" "github.com/tidepool-org/platform/structure/validator" - - platformErrors "github.com/tidepool-org/platform/errors" ) const ( @@ -75,15 +73,11 @@ func DayIndex(day string) (int, error) { } } -func ErrorValueStringDayNotValid(value string) error { - return platformErrors.Preparedf(validator.ErrorCodeValueNotValid, "value is not valid", "value %q is not valid as a day of the week", value) -} - func ValidateDayOfWeek(value string) error { if value == "" { return validator.ErrorValueEmpty() } else if !slices.Contains(DaysOfWeek(), strings.ToLower(value)) { - return ErrorValueStringDayNotValid(value) + return validator.ErrorValueStringNotOneOf(value, DaysOfWeek()) } return nil } diff --git a/data/types/common/day_test.go b/data/types/common/day_test.go index 6752afce1a..94e8b53c1a 100644 --- a/data/types/common/day_test.go +++ b/data/types/common/day_test.go @@ -7,6 +7,7 @@ import ( . "github.com/onsi/gomega" "github.com/tidepool-org/platform/data/types/common" + "github.com/tidepool-org/platform/structure/validator" ) var _ = Describe("Day", func() { @@ -81,4 +82,21 @@ var _ = Describe("Day", func() { Entry("is an invalid string", "invalid", 0, errors.New("invalid day of the week")), ) }) + + Context("ValidateDayOfWeek", func() { + DescribeTable("return error when invalid", + func(day string, expectedErr error) { + actualError := common.ValidateDayOfWeek(day) + if expectedErr == nil { + Expect(actualError).To(BeNil()) + } else { + Expect(actualError.Error()).To(Equal(expectedErr.Error())) + } + }, + Entry("ok when same case", "tuesday", nil), + Entry("ok when mixed case", "FriDAY", nil), + Entry("ok when uppercase", "SUNDAY", nil), + Entry("invalid when not a day of the week", "monday2", validator.ErrorValueStringNotOneOf("monday2", common.DaysOfWeek())), + ) + }) }) From 361b697b78ebde96c8fc78e4a36c246371a44a0c Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 4 Jul 2024 10:54:17 +1200 Subject: [PATCH 338/413] updates for dataset verification tool --- .../utils/data_migration.go | 113 +++++++++--------- .../utils/data_verify.go | 31 +++-- .../utils/data_verify_test.go | 6 +- .../utils/output.go | 30 +++++ .../verify/verify.go | 10 +- 5 files changed, 122 insertions(+), 68 deletions(-) create mode 100644 migrations/20231128_jellyfish_migration/utils/output.go diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go index ffb7f052f8..f1cf30c168 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration.go @@ -2,7 +2,6 @@ package utils import ( "context" - "encoding/json" "errors" "fmt" "log" @@ -270,20 +269,22 @@ func (m *DataMigration) writeErrors() { m.groupedErrors = map[string][]ErrorData{} } for group, errors := range m.groupedErrors { - f, err := m.createFile("error", group, "%s.log") - if err != nil { - log.Println(err) - os.Exit(1) - } - defer f.Close() - for _, data := range errors { - errJSON, err := json.Marshal(data) - if err != nil { - log.Println(err) - os.Exit(1) - } - f.WriteString(string(errJSON) + "\n") - } + logPath := filepath.Join(".", "error", fmt.Sprintf("%s.log", group)) + writeFileData(errors, logPath) + // f, err := m.createFile("error", group, "%s.log") + // if err != nil { + // log.Println(err) + // os.Exit(1) + // } + // defer f.Close() + // for _, data := range errors { + // errJSON, err := json.Marshal(data) + // if err != nil { + // log.Println(err) + // os.Exit(1) + // } + // f.WriteString(string(errJSON) + "\n") + // } m.groupedErrors[group] = []ErrorData{} } } @@ -294,20 +295,24 @@ func (m *DataMigration) writeAudit() { return } for group, diffs := range m.groupedDiffs { - f, err := m.createFile("audit", group, "%s.json") - if err != nil { - log.Println(err) - os.Exit(1) - } - defer f.Close() - for _, data := range diffs { - diffJSON, err := json.Marshal(data) - if err != nil { - log.Println(err) - os.Exit(1) - } - f.WriteString(string(diffJSON) + "\n") - } + + logPath := filepath.Join(".", "audit", fmt.Sprintf("%s.json", group)) + writeFileData(diffs, logPath) + + // f, err := m.createFile("audit", group, "%s.json") + // if err != nil { + // log.Println(err) + // os.Exit(1) + // } + // defer f.Close() + // for _, data := range diffs { + // diffJSON, err := json.Marshal(data) + // if err != nil { + // log.Println(err) + // os.Exit(1) + // } + // f.WriteString(string(diffJSON) + "\n") + // } m.groupedDiffs[group] = []UpdateData{} } } @@ -326,28 +331,28 @@ func (m *DataMigration) writeLastProcessed(itemID string) { } } -func (m *DataMigration) createFile(fileType string, dataGroup string, logName string) (*os.File, error) { - - var err error - if fileType == "" { - err = errors.Join(err, errors.New("missing file type")) - } - if dataGroup == "" { - err = errors.Join(err, errors.New("missing data group")) - } - if logName == "" { - err = errors.Join(err, errors.New("missing log group")) - } - if err != nil { - return nil, err - } - - logName = fmt.Sprintf(logName, dataGroup) - logPath := filepath.Join(".", fileType) - err = os.MkdirAll(logPath, os.ModePerm) - if err != nil { - return nil, err - } - - return os.OpenFile(logPath+"/"+logName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) -} +// func (m *DataMigration) createFile(fileType string, dataGroup string, logName string) (*os.File, error) { + +// var err error +// if fileType == "" { +// err = errors.Join(err, errors.New("missing file type")) +// } +// if dataGroup == "" { +// err = errors.Join(err, errors.New("missing data group")) +// } +// if logName == "" { +// err = errors.Join(err, errors.New("missing log group")) +// } +// if err != nil { +// return nil, err +// } + +// logName = fmt.Sprintf(logName, dataGroup) +// logPath := filepath.Join(".", fileType) +// err = os.MkdirAll(logPath, os.ModePerm) +// if err != nil { +// return nil, err +// } + +// return os.OpenFile(logPath+"/"+logName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) +// } diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 4ffbb78580..3447fca5ca 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "log" + "path/filepath" "strings" "github.com/r3labs/diff/v3" @@ -18,11 +19,7 @@ type DataVerify struct { dataC *mongo.Collection } -func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[string]interface{}) ([]string, error) { - - if len(platformData) != len(jellyfishData) { - log.Printf("NOTE: datasets mismatch platform (%d) vs jellyfish (%d)", len(platformData), len(jellyfishData)) - } +func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[string]interface{}, useSubset bool) ([]string, error) { // small batches or the diff takes to long var processBatch = func(batchPlatform, batchJellyfish []map[string]interface{}) ([]string, error) { @@ -122,10 +119,10 @@ func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[ return differences, nil } - if len(platformData) <= 100 { - return processAllData() + if useSubset && len(platformData) >= 100 { + return processSubsetOfData() } - return processSubsetOfData() + return processAllData() } func NewVerifier(ctx context.Context, dataC *mongo.Collection) (*DataVerify, error) { @@ -200,7 +197,7 @@ func (m *DataVerify) FetchBlobIDs() ([]map[string]interface{}, error) { return blobData, nil } -func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUploadID string, dataTyes []string) error { +func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUploadID string, dataTyes []string, useSubset bool) error { if len(dataTyes) == 0 { dataTyes = DatasetTypes @@ -220,7 +217,21 @@ func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUpload for dType, jfSet := range jellyfishDataset { - differences, err := CompareDatasets(platformDataset[dType], jfSet) + pfSet := platformDataset[dType] + + if len(pfSet) != len(jfSet) { + log.Printf("NOTE: datasets mismatch platform (%d) vs jellyfish (%d)", len(pfSet), len(jfSet)) + compareDir := fmt.Sprintf("%s_%s", platformUploadID, jellyfishUploadID) + jellyfishPath := filepath.Join(".", "compare", compareDir, fmt.Sprintf("jf_%s.json", jellyfishUploadID)) + platformPath := filepath.Join(".", "compare", compareDir, fmt.Sprintf("pf_%s.json", platformUploadID)) + log.Printf("jellyfish data written %s", jellyfishPath) + log.Printf("platform data written %s", platformPath) + writeFileData(jfSet, jellyfishPath) + writeFileData(pfSet, platformPath) + continue + } + + differences, err := CompareDatasets(pfSet, jfSet, useSubset) if err != nil { return err } diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify_test.go b/migrations/20231128_jellyfish_migration/utils/data_verify_test.go index 69460cbd90..fc7d898f91 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify_test.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify_test.go @@ -15,14 +15,14 @@ var _ = Describe("CompareDatasets", func() { It("will genterate a list of differences between two datasets", func() { jfDataset := test.BulkJellyfishData("test-device-88x89", "test-group-id", "test-user-id-123", 2) platformDataset := test.BulkJellyfishData("test-device-88x89", "test-group-id_2", "test-user-id-987", 2) - changes, err := utils.CompareDatasets(jfDataset, platformDataset) + changes, err := utils.CompareDatasets(jfDataset, platformDataset, false) Expect(err).To(BeNil()) Expect(changes).ToNot(BeEmpty()) }) It("will genterate no differences when the datasets are the same ", func() { jfDataset := test.BulkJellyfishData("test-device-88x89", "test-group-id", "test-user-id-123", 100) - changes, err := utils.CompareDatasets(jfDataset, jfDataset) + changes, err := utils.CompareDatasets(jfDataset, jfDataset, false) Expect(err).To(BeNil()) Expect(changes).To(BeEmpty()) }) @@ -38,7 +38,7 @@ var _ = Describe("CompareDatasets", func() { datasetCopy = append(datasetCopy, datum) } - changes, err := utils.CompareDatasets(jfDataset, datasetCopy) + changes, err := utils.CompareDatasets(jfDataset, datasetCopy, false) Expect(err).To(BeNil()) Expect(changes).To(BeEmpty()) }) diff --git a/migrations/20231128_jellyfish_migration/utils/output.go b/migrations/20231128_jellyfish_migration/utils/output.go new file mode 100644 index 0000000000..a477bddd59 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/utils/output.go @@ -0,0 +1,30 @@ +package utils + +import ( + "encoding/json" + "log" + "os" +) + +func writeFileData(data interface{}, fileName string) { + if data == nil || fileName == "" { + return + } + + var handleErr = func(err error) { + if err != nil { + log.Println(err) + os.Exit(1) + } + } + + err := os.MkdirAll(fileName, os.ModePerm) + handleErr(err) + f, err := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + handleErr(err) + + defer f.Close() + jsonData, err := json.Marshal(data) + handleErr(err) + f.WriteString(string(jsonData) + "\n") +} diff --git a/migrations/20231128_jellyfish_migration/verify/verify.go b/migrations/20231128_jellyfish_migration/verify/verify.go index cfb30b0ead..54dc516031 100644 --- a/migrations/20231128_jellyfish_migration/verify/verify.go +++ b/migrations/20231128_jellyfish_migration/verify/verify.go @@ -25,6 +25,7 @@ type Verify struct { type config struct { mongoURI string findBlobs bool + useSubset bool platformUploadID string jellyfishUploadID string dataTypes string @@ -35,6 +36,7 @@ const PlatformUploadIDFlag = "upload-id-platform" const JellyfishUploadIDFlag = "upload-id-jellyfish" const FindBlobFlag = "find-blobs" const DataTypesFlag = "data-types" +const UseSubsetFlag = "use-subset" func main() { ctx := context.Background() @@ -98,7 +100,7 @@ func (m *Verify) RunAndExit() { return fmt.Errorf("unable to create verification utils : %w", err) } - err = m.verificationUtil.Verify("ref", m.config.platformUploadID, m.config.jellyfishUploadID, strings.Split(m.config.dataTypes, ",")) + err = m.verificationUtil.Verify("ref", m.config.platformUploadID, m.config.jellyfishUploadID, strings.Split(m.config.dataTypes, ","), m.config.useSubset) if err != nil { log.Printf("error running verify : %s", err.Error()) } @@ -148,6 +150,12 @@ func (m *Verify) Initialize() error { Destination: &m.config.findBlobs, Required: false, }, + cli.BoolFlag{ + Name: UseSubsetFlag, + Usage: "use a subset of data to compare", + Destination: &m.config.useSubset, + Required: false, + }, cli.StringFlag{ Name: MongoURIFlag, Usage: "mongo connection URI", From 6cb3072eee9cf3440387b191935d5459af5dc515 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 4 Jul 2024 11:07:09 +1200 Subject: [PATCH 339/413] seperate file name and path --- .../utils/data_migration.go | 62 +------------------ .../utils/data_verify.go | 11 ++-- .../utils/output.go | 9 +-- 3 files changed, 11 insertions(+), 71 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go index f1cf30c168..eeaca6adc7 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration.go @@ -269,22 +269,7 @@ func (m *DataMigration) writeErrors() { m.groupedErrors = map[string][]ErrorData{} } for group, errors := range m.groupedErrors { - logPath := filepath.Join(".", "error", fmt.Sprintf("%s.log", group)) - writeFileData(errors, logPath) - // f, err := m.createFile("error", group, "%s.log") - // if err != nil { - // log.Println(err) - // os.Exit(1) - // } - // defer f.Close() - // for _, data := range errors { - // errJSON, err := json.Marshal(data) - // if err != nil { - // log.Println(err) - // os.Exit(1) - // } - // f.WriteString(string(errJSON) + "\n") - // } + writeFileData(errors, filepath.Join(".", "error"), fmt.Sprintf("%s.log", group)) m.groupedErrors[group] = []ErrorData{} } } @@ -295,24 +280,7 @@ func (m *DataMigration) writeAudit() { return } for group, diffs := range m.groupedDiffs { - - logPath := filepath.Join(".", "audit", fmt.Sprintf("%s.json", group)) - writeFileData(diffs, logPath) - - // f, err := m.createFile("audit", group, "%s.json") - // if err != nil { - // log.Println(err) - // os.Exit(1) - // } - // defer f.Close() - // for _, data := range diffs { - // diffJSON, err := json.Marshal(data) - // if err != nil { - // log.Println(err) - // os.Exit(1) - // } - // f.WriteString(string(diffJSON) + "\n") - // } + writeFileData(diffs, filepath.Join(".", "audit"), fmt.Sprintf("%s.json", group)) m.groupedDiffs[group] = []UpdateData{} } } @@ -330,29 +298,3 @@ func (m *DataMigration) writeLastProcessed(itemID string) { } } } - -// func (m *DataMigration) createFile(fileType string, dataGroup string, logName string) (*os.File, error) { - -// var err error -// if fileType == "" { -// err = errors.Join(err, errors.New("missing file type")) -// } -// if dataGroup == "" { -// err = errors.Join(err, errors.New("missing data group")) -// } -// if logName == "" { -// err = errors.Join(err, errors.New("missing log group")) -// } -// if err != nil { -// return nil, err -// } - -// logName = fmt.Sprintf(logName, dataGroup) -// logPath := filepath.Join(".", fileType) -// err = os.MkdirAll(logPath, os.ModePerm) -// if err != nil { -// return nil, err -// } - -// return os.OpenFile(logPath+"/"+logName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) -// } diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 3447fca5ca..45a21267db 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -221,13 +221,10 @@ func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUpload if len(pfSet) != len(jfSet) { log.Printf("NOTE: datasets mismatch platform (%d) vs jellyfish (%d)", len(pfSet), len(jfSet)) - compareDir := fmt.Sprintf("%s_%s", platformUploadID, jellyfishUploadID) - jellyfishPath := filepath.Join(".", "compare", compareDir, fmt.Sprintf("jf_%s.json", jellyfishUploadID)) - platformPath := filepath.Join(".", "compare", compareDir, fmt.Sprintf("pf_%s.json", platformUploadID)) - log.Printf("jellyfish data written %s", jellyfishPath) - log.Printf("platform data written %s", platformPath) - writeFileData(jfSet, jellyfishPath) - writeFileData(pfSet, platformPath) + comparePath := filepath.Join(".", "compare", fmt.Sprintf("%s_%s", platformUploadID, jellyfishUploadID)) + log.Printf("data written to %s", comparePath) + writeFileData(jfSet, comparePath, fmt.Sprintf("jf_%s.json", jellyfishUploadID)) + writeFileData(pfSet, comparePath, fmt.Sprintf("pf_%s.json", platformUploadID)) continue } diff --git a/migrations/20231128_jellyfish_migration/utils/output.go b/migrations/20231128_jellyfish_migration/utils/output.go index a477bddd59..d47bbb3a74 100644 --- a/migrations/20231128_jellyfish_migration/utils/output.go +++ b/migrations/20231128_jellyfish_migration/utils/output.go @@ -2,12 +2,13 @@ package utils import ( "encoding/json" + "fmt" "log" "os" ) -func writeFileData(data interface{}, fileName string) { - if data == nil || fileName == "" { +func writeFileData(data interface{}, path string, name string) { + if data == nil || path == "" || name == "" { return } @@ -18,9 +19,9 @@ func writeFileData(data interface{}, fileName string) { } } - err := os.MkdirAll(fileName, os.ModePerm) + err := os.MkdirAll(path, os.ModePerm) handleErr(err) - f, err := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + f, err := os.OpenFile(fmt.Sprintf("%s/%s", path, name), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) handleErr(err) defer f.Close() From 36ca339cf8f1c6ac13d8cd916d58042083940e7c Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 4 Jul 2024 12:35:05 +1200 Subject: [PATCH 340/413] also group by subtype if present --- .../utils/data_verify.go | 79 ++++++++----------- 1 file changed, 35 insertions(+), 44 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 45a21267db..584fa87a95 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -23,46 +23,7 @@ func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[ // small batches or the diff takes to long var processBatch = func(batchPlatform, batchJellyfish []map[string]interface{}) ([]string, error) { - - cleanedJellyfish := []map[string]interface{}{} - cleanedPlatform := []map[string]interface{}{} - - doNotCompare := []string{ - "_active", - "_archivedTime", - "createdTime", - "deduplicator", - "_deduplicator", - "_groupId", - "guid", - "_id", - "id", - "modifiedTime", - "payload", - "provenance", - "revision", - "_schemaVersion", - "time", - "_userId", - "uploadId", - "_version", - } - - for _, datum := range batchPlatform { - for _, key := range doNotCompare { - delete(datum, key) - } - cleanedPlatform = append(cleanedPlatform, datum) - } - - for _, datum := range batchJellyfish { - for _, key := range doNotCompare { - delete(datum, key) - } - cleanedJellyfish = append(cleanedJellyfish, datum) - } - - changelog, err := diff.Diff(cleanedPlatform, cleanedJellyfish, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) + changelog, err := diff.Diff(batchPlatform, batchJellyfish, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) if err != nil { return nil, err } @@ -152,11 +113,41 @@ func (m *DataVerify) fetchDataSet(uploadID string, dataTypes []string) (map[stri dset := []map[string]interface{}{} - dDataCursor, err := m.dataC.Find(m.ctx, bson.M{ + filter := bson.M{ "uploadId": uploadID, "type": dType, - }, &options.FindOptions{ - Sort: bson.M{"time": 1}, + } + + sort := bson.D{{Key: "time", Value: 1}} + + if dType == "deviceEvent" || dType == "bolus" { + sort = bson.D{{Key: "time", Value: 1}, {Key: "subType", Value: 1}} + } + + excludedFeilds := bson.M{ + "_active": 0, + "_archivedTime": 0, + "createdTime": 0, + "deduplicator": 0, + "_deduplicator": 0, + "_groupId": 0, + "guid": 0, + "_id": 0, + "id": 0, + "modifiedTime": 0, + "payload": 0, + "provenance": 0, + "revision": 0, + "_schemaVersion": 0, + "time": 0, + "_userId": 0, + "uploadId": 0, + "_version": 0, + } + + dDataCursor, err := m.dataC.Find(m.ctx, filter, &options.FindOptions{ + Sort: sort, + Projection: excludedFeilds, }) if err != nil { return nil, err @@ -221,7 +212,7 @@ func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUpload if len(pfSet) != len(jfSet) { log.Printf("NOTE: datasets mismatch platform (%d) vs jellyfish (%d)", len(pfSet), len(jfSet)) - comparePath := filepath.Join(".", "compare", fmt.Sprintf("%s_%s", platformUploadID, jellyfishUploadID)) + comparePath := filepath.Join(".", "_compare", fmt.Sprintf("%s_%s", platformUploadID, jellyfishUploadID)) log.Printf("data written to %s", comparePath) writeFileData(jfSet, comparePath, fmt.Sprintf("jf_%s.json", jellyfishUploadID)) writeFileData(pfSet, comparePath, fmt.Sprintf("pf_%s.json", platformUploadID)) From e354180058ba9dfe7ff99d1bc28c56226d30944c Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 4 Jul 2024 13:38:03 +1200 Subject: [PATCH 341/413] simplify compare sets --- .../utils/data_verify.go | 78 +++++++++---------- 1 file changed, 36 insertions(+), 42 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 584fa87a95..dba4190623 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -21,39 +21,36 @@ type DataVerify struct { func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[string]interface{}, useSubset bool) ([]string, error) { + diffs := []string{} + // small batches or the diff takes to long - var processBatch = func(batchPlatform, batchJellyfish []map[string]interface{}) ([]string, error) { + var processBatch = func(batchPlatform, batchJellyfish []map[string]interface{}) error { changelog, err := diff.Diff(batchPlatform, batchJellyfish, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) if err != nil { - return nil, err + return err } - diffs := []string{} for _, change := range changelog { diffs = append(diffs, fmt.Sprintf("%s => platform:[%v] jellyfish:[%v]", strings.Join(change.Path, "."), change.From, change.To)) } - return diffs, nil + return nil } var processAllData = func() ([]string, error) { batch := 100 - differences := []string{} for i := 0; i < len(platformData); i += batch { j := i + batch if j > len(platformData) { j = len(platformData) } - if batchDiff, err := processBatch(platformData[i:j], jellyfishData[i:j]); err != nil { + if err := processBatch(platformData[i:j], jellyfishData[i:j]); err != nil { return nil, err - } else { - differences = append(differences, batchDiff...) } } - return differences, nil + return diffs, nil } var processSubsetOfData = func() ([]string, error) { - differences := []string{} batch := 20 quater := len(platformData) / 4 batchStarts := []int{ @@ -71,13 +68,11 @@ func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[ if j > len(platformData) { j = len(platformData) } - if batchDiff, err := processBatch(platformData[startAt:j], jellyfishData[startAt:j]); err != nil { + if err := processBatch(platformData[startAt:j], jellyfishData[startAt:j]); err != nil { return nil, err - } else { - differences = append(differences, batchDiff...) } } - return differences, nil + return diffs, nil } if useSubset && len(platformData) >= 100 { @@ -125,24 +120,28 @@ func (m *DataVerify) fetchDataSet(uploadID string, dataTypes []string) (map[stri } excludedFeilds := bson.M{ - "_active": 0, - "_archivedTime": 0, - "createdTime": 0, - "deduplicator": 0, - "_deduplicator": 0, - "_groupId": 0, - "guid": 0, - "_id": 0, - "id": 0, - "modifiedTime": 0, - "payload": 0, - "provenance": 0, - "revision": 0, - "_schemaVersion": 0, - "time": 0, - "_userId": 0, - "uploadId": 0, - "_version": 0, + "_active": 0, + "_archivedTime": 0, + "createdTime": 0, + "clockDriftOffset": 0, + "conversionOffset": 0, + "deduplicator": 0, + "_deduplicator": 0, + "_groupId": 0, + "guid": 0, + "_id": 0, + "id": 0, + "modifiedTime": 0, + "payload": 0, + "provenance": 0, + "revision": 0, + "_schemaVersion": 0, + "time": 0, + "timezoneOffset": 0, + "type": 0, + "_userId": 0, + "uploadId": 0, + "_version": 0, } dDataCursor, err := m.dataC.Find(m.ctx, filter, &options.FindOptions{ @@ -209,23 +208,18 @@ func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUpload for dType, jfSet := range jellyfishDataset { pfSet := platformDataset[dType] - + comparePath := filepath.Join(".", "_compare", fmt.Sprintf("%s_%s", platformUploadID, jellyfishUploadID)) + log.Printf("data written to %s", comparePath) if len(pfSet) != len(jfSet) { log.Printf("NOTE: datasets mismatch platform (%d) vs jellyfish (%d)", len(pfSet), len(jfSet)) - comparePath := filepath.Join(".", "_compare", fmt.Sprintf("%s_%s", platformUploadID, jellyfishUploadID)) - log.Printf("data written to %s", comparePath) - writeFileData(jfSet, comparePath, fmt.Sprintf("jf_%s.json", jellyfishUploadID)) - writeFileData(pfSet, comparePath, fmt.Sprintf("pf_%s.json", platformUploadID)) - continue + writeFileData(jfSet, comparePath, fmt.Sprintf("raw_%s_jf_%s.json", dType, jellyfishUploadID)) + writeFileData(pfSet, comparePath, fmt.Sprintf("raw_%s_pf_%s.json", dType, platformUploadID)) } - differences, err := CompareDatasets(pfSet, jfSet, useSubset) if err != nil { return err } - for _, v := range differences { - log.Printf("%s.%s", dType, v) - } + writeFileData(differences, comparePath, fmt.Sprintf("%sdiff.json", dType)) } return nil From 6b74c8ef340c79031033a7591342d7f4aa283762 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 4 Jul 2024 14:17:01 +1200 Subject: [PATCH 342/413] diff row by row --- .../utils/data_migration.go | 4 +-- .../utils/data_verify.go | 29 ++++++++++++------- .../utils/output.go | 13 ++++++--- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go index eeaca6adc7..102b2255df 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration.go @@ -269,7 +269,7 @@ func (m *DataMigration) writeErrors() { m.groupedErrors = map[string][]ErrorData{} } for group, errors := range m.groupedErrors { - writeFileData(errors, filepath.Join(".", "error"), fmt.Sprintf("%s.log", group)) + writeFileData(errors, filepath.Join(".", "error"), fmt.Sprintf("%s.log", group), false) m.groupedErrors[group] = []ErrorData{} } } @@ -280,7 +280,7 @@ func (m *DataMigration) writeAudit() { return } for group, diffs := range m.groupedDiffs { - writeFileData(diffs, filepath.Join(".", "audit"), fmt.Sprintf("%s.json", group)) + writeFileData(diffs, filepath.Join(".", "audit"), fmt.Sprintf("%s.json", group), true) m.groupedDiffs[group] = []UpdateData{} } } diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index dba4190623..41d6a802b4 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -25,12 +25,22 @@ func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[ // small batches or the diff takes to long var processBatch = func(batchPlatform, batchJellyfish []map[string]interface{}) error { - changelog, err := diff.Diff(batchPlatform, batchJellyfish, diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) - if err != nil { - return err - } - for _, change := range changelog { - diffs = append(diffs, fmt.Sprintf("%s => platform:[%v] jellyfish:[%v]", strings.Join(change.Path, "."), change.From, change.To)) + + // assumption is the items are ordered + for id, platformDatum := range batchPlatform { + + if batchJellyfish[id] == nil { + log.Println("no matching value in the jellyfish data") + break + } + + changelog, err := diff.Diff(platformDatum, batchJellyfish[id], diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) + if err != nil { + return err + } + for _, change := range changelog { + diffs = append(diffs, fmt.Sprintf("%s => platform:[%v] jellyfish:[%v]", strings.Join(change.Path, "."), change.From, change.To)) + } } return nil } @@ -206,20 +216,19 @@ func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUpload log.Printf("Compare platform[%s] vs jellyfish[%s]", platformUploadID, jellyfishUploadID) for dType, jfSet := range jellyfishDataset { - pfSet := platformDataset[dType] comparePath := filepath.Join(".", "_compare", fmt.Sprintf("%s_%s", platformUploadID, jellyfishUploadID)) log.Printf("data written to %s", comparePath) if len(pfSet) != len(jfSet) { log.Printf("NOTE: datasets mismatch platform (%d) vs jellyfish (%d)", len(pfSet), len(jfSet)) - writeFileData(jfSet, comparePath, fmt.Sprintf("raw_%s_jf_%s.json", dType, jellyfishUploadID)) - writeFileData(pfSet, comparePath, fmt.Sprintf("raw_%s_pf_%s.json", dType, platformUploadID)) + writeFileData(jfSet, comparePath, fmt.Sprintf("raw_%s_jf_%s.json", dType, jellyfishUploadID), true) + writeFileData(pfSet, comparePath, fmt.Sprintf("raw_%s_pf_%s.json", dType, platformUploadID), true) } differences, err := CompareDatasets(pfSet, jfSet, useSubset) if err != nil { return err } - writeFileData(differences, comparePath, fmt.Sprintf("%sdiff.json", dType)) + writeFileData(differences, comparePath, fmt.Sprintf("%s_diff.log", dType), false) } return nil diff --git a/migrations/20231128_jellyfish_migration/utils/output.go b/migrations/20231128_jellyfish_migration/utils/output.go index d47bbb3a74..7182bd8285 100644 --- a/migrations/20231128_jellyfish_migration/utils/output.go +++ b/migrations/20231128_jellyfish_migration/utils/output.go @@ -7,7 +7,7 @@ import ( "os" ) -func writeFileData(data interface{}, path string, name string) { +func writeFileData(data interface{}, path string, name string, asJSON bool) { if data == nil || path == "" || name == "" { return } @@ -25,7 +25,12 @@ func writeFileData(data interface{}, path string, name string) { handleErr(err) defer f.Close() - jsonData, err := json.Marshal(data) - handleErr(err) - f.WriteString(string(jsonData) + "\n") + + if asJSON { + jsonData, err := json.Marshal(data) + handleErr(err) + f.WriteString(string(jsonData) + "\n") + return + } + f.WriteString(fmt.Sprintf("%v", data)) } From 033e3a08ef87f225d2868283206a356be3a57cc5 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 4 Jul 2024 14:35:48 +1200 Subject: [PATCH 343/413] diff datum by datum --- .../utils/data_verify.go | 127 +++++++++--------- 1 file changed, 65 insertions(+), 62 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 41d6a802b4..5a8b9a436c 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -6,7 +6,6 @@ import ( "fmt" "log" "path/filepath" - "strings" "github.com/r3labs/diff/v3" "go.mongodb.org/mongo-driver/bson" @@ -19,76 +18,80 @@ type DataVerify struct { dataC *mongo.Collection } -func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[string]interface{}, useSubset bool) ([]string, error) { +func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[string]interface{}, useSubset bool) (map[string]interface{}, error) { - diffs := []string{} + diffs := map[string]interface{}{} - // small batches or the diff takes to long - var processBatch = func(batchPlatform, batchJellyfish []map[string]interface{}) error { - - // assumption is the items are ordered - for id, platformDatum := range batchPlatform { - - if batchJellyfish[id] == nil { - log.Println("no matching value in the jellyfish data") - break - } - - changelog, err := diff.Diff(platformDatum, batchJellyfish[id], diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) - if err != nil { - return err - } - for _, change := range changelog { - diffs = append(diffs, fmt.Sprintf("%s => platform:[%v] jellyfish:[%v]", strings.Join(change.Path, "."), change.From, change.To)) - } - } - return nil - } + // diffs := []string{} - var processAllData = func() ([]string, error) { - batch := 100 - for i := 0; i < len(platformData); i += batch { - j := i + batch - if j > len(platformData) { - j = len(platformData) - } - if err := processBatch(platformData[i:j], jellyfishData[i:j]); err != nil { - return nil, err - } - } - return diffs, nil - } + // small batches or the diff takes to long + //var processBatch = func(batchPlatform, batchJellyfish []map[string]interface{}) error { - var processSubsetOfData = func() ([]string, error) { + // assumption is the items are ordered + for id, platformDatum := range platformData { - batch := 20 - quater := len(platformData) / 4 - batchStarts := []int{ - 0, - quater, - quater * 2, - quater * 3, + if jellyfishData[id] == nil { + log.Println("no matching value in the jellyfish data") + break } - log.Printf("NOTE: comparing a subset of all [%d] datum with a batch size [%d] starting at [%v] ", len(platformData), batch, batchStarts) - - for _, startAt := range batchStarts { - j := startAt + batch - - if j > len(platformData) { - j = len(platformData) - } - if err := processBatch(platformData[startAt:j], jellyfishData[startAt:j]); err != nil { - return nil, err - } + changelog, err := diff.Diff(platformDatum, jellyfishData[id], diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) + if err != nil { + return nil, err } - return diffs, nil - } + diffs[fmt.Sprintf("platform_%d", id)] = changelog - if useSubset && len(platformData) >= 100 { - return processSubsetOfData() + // for _, change := range changelog { + // diffs = append(diffs, fmt.Sprintf("%s => platform:[%v] jellyfish:[%v]", strings.Join(change.Path, "."), change.From, change.To)) + // } } - return processAllData() + return diffs, nil + //} + + // var processAllData = func() ([]string, error) { + // batch := 100 + // for i := 0; i < len(platformData); i += batch { + // j := i + batch + // if j > len(platformData) { + // j = len(platformData) + // } + // if err := processBatch(platformData[i:j], jellyfishData[i:j]); err != nil { + // return nil, err + // } + // } + // return diffs, nil + // } + + // var processSubsetOfData = func() ([]string, error) { + + // batch := 20 + // quater := len(platformData) / 4 + // batchStarts := []int{ + // 0, + // quater, + // quater * 2, + // quater * 3, + // } + + // log.Printf("NOTE: comparing a subset of all [%d] datum with a batch size [%d] starting at [%v] ", len(platformData), batch, batchStarts) + + // for _, startAt := range batchStarts { + // j := startAt + batch + + // if j > len(platformData) { + // j = len(platformData) + // } + // if err := processBatch(platformData[startAt:j], jellyfishData[startAt:j]); err != nil { + // return nil, err + // } + // } + // return diffs, nil + // } + + // if useSubset && len(platformData) >= 100 { + // return processSubsetOfData() + // } + // return processAllData() } func NewVerifier(ctx context.Context, dataC *mongo.Collection) (*DataVerify, error) { @@ -228,7 +231,7 @@ func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUpload if err != nil { return err } - writeFileData(differences, comparePath, fmt.Sprintf("%s_diff.log", dType), false) + writeFileData(differences, comparePath, fmt.Sprintf("%s_diff.json", dType), true) } return nil From 092dead6769c310cdfc219ea7d89448a85425bcd Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 4 Jul 2024 16:50:22 +1200 Subject: [PATCH 344/413] find missing datum if there are any --- .../utils/data_verify.go | 86 +++++-------------- .../utils/data_verify_test.go | 23 +---- 2 files changed, 25 insertions(+), 84 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 5a8b9a436c..aced5fb269 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -18,80 +18,22 @@ type DataVerify struct { dataC *mongo.Collection } -func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[string]interface{}, useSubset bool) (map[string]interface{}, error) { - +func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[string]interface{}) (map[string]interface{}, error) { diffs := map[string]interface{}{} - - // diffs := []string{} - - // small batches or the diff takes to long - //var processBatch = func(batchPlatform, batchJellyfish []map[string]interface{}) error { - - // assumption is the items are ordered for id, platformDatum := range platformData { - if jellyfishData[id] == nil { log.Println("no matching value in the jellyfish data") break } - changelog, err := diff.Diff(platformDatum, jellyfishData[id], diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) if err != nil { return nil, err } - diffs[fmt.Sprintf("platform_%d", id)] = changelog - - // for _, change := range changelog { - // diffs = append(diffs, fmt.Sprintf("%s => platform:[%v] jellyfish:[%v]", strings.Join(change.Path, "."), change.From, change.To)) - // } + if len(changelog) > 0 { + diffs[fmt.Sprintf("platform_%d", id)] = changelog + } } return diffs, nil - //} - - // var processAllData = func() ([]string, error) { - // batch := 100 - // for i := 0; i < len(platformData); i += batch { - // j := i + batch - // if j > len(platformData) { - // j = len(platformData) - // } - // if err := processBatch(platformData[i:j], jellyfishData[i:j]); err != nil { - // return nil, err - // } - // } - // return diffs, nil - // } - - // var processSubsetOfData = func() ([]string, error) { - - // batch := 20 - // quater := len(platformData) / 4 - // batchStarts := []int{ - // 0, - // quater, - // quater * 2, - // quater * 3, - // } - - // log.Printf("NOTE: comparing a subset of all [%d] datum with a batch size [%d] starting at [%v] ", len(platformData), batch, batchStarts) - - // for _, startAt := range batchStarts { - // j := startAt + batch - - // if j > len(platformData) { - // j = len(platformData) - // } - // if err := processBatch(platformData[startAt:j], jellyfishData[startAt:j]); err != nil { - // return nil, err - // } - // } - // return diffs, nil - // } - - // if useSubset && len(platformData) >= 100 { - // return processSubsetOfData() - // } - // return processAllData() } func NewVerifier(ctx context.Context, dataC *mongo.Collection) (*DataVerify, error) { @@ -200,6 +142,21 @@ func (m *DataVerify) FetchBlobIDs() ([]map[string]interface{}, error) { return blobData, nil } +func getMissing(a []map[string]interface{}, b []map[string]interface{}) []map[string]interface{} { + missing := []map[string]interface{}{} + ma := make(map[string]bool, len(a)) + for _, ka := range a { + ma[fmt.Sprintf("%v", ka["deviceTime"])] = true + } + for _, kb := range b { + if !ma[fmt.Sprintf("%v", kb["deviceTime"])] { + missing = append(missing, kb) + } + } + return missing + +} + func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUploadID string, dataTyes []string, useSubset bool) error { if len(dataTyes) == 0 { @@ -224,10 +181,13 @@ func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUpload log.Printf("data written to %s", comparePath) if len(pfSet) != len(jfSet) { log.Printf("NOTE: datasets mismatch platform (%d) vs jellyfish (%d)", len(pfSet), len(jfSet)) + missing := getMissing(pfSet, jfSet) + writeFileData(missing, comparePath, fmt.Sprintf("missing_%s.json", dType), true) writeFileData(jfSet, comparePath, fmt.Sprintf("raw_%s_jf_%s.json", dType, jellyfishUploadID), true) writeFileData(pfSet, comparePath, fmt.Sprintf("raw_%s_pf_%s.json", dType, platformUploadID), true) + break } - differences, err := CompareDatasets(pfSet, jfSet, useSubset) + differences, err := CompareDatasets(pfSet, jfSet) if err != nil { return err } diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify_test.go b/migrations/20231128_jellyfish_migration/utils/data_verify_test.go index fc7d898f91..9dc2715da5 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify_test.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify_test.go @@ -1,8 +1,6 @@ package utils_test import ( - "fmt" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -15,32 +13,15 @@ var _ = Describe("CompareDatasets", func() { It("will genterate a list of differences between two datasets", func() { jfDataset := test.BulkJellyfishData("test-device-88x89", "test-group-id", "test-user-id-123", 2) platformDataset := test.BulkJellyfishData("test-device-88x89", "test-group-id_2", "test-user-id-987", 2) - changes, err := utils.CompareDatasets(jfDataset, platformDataset, false) + changes, err := utils.CompareDatasets(jfDataset, platformDataset) Expect(err).To(BeNil()) Expect(changes).ToNot(BeEmpty()) }) It("will genterate no differences when the datasets are the same ", func() { jfDataset := test.BulkJellyfishData("test-device-88x89", "test-group-id", "test-user-id-123", 100) - changes, err := utils.CompareDatasets(jfDataset, jfDataset, false) + changes, err := utils.CompareDatasets(jfDataset, jfDataset) Expect(err).To(BeNil()) Expect(changes).To(BeEmpty()) }) - - It("will not compare defined fields", func() { - jfDataset := test.BulkJellyfishData("test-device-88x89", "test-group-id", "test-user-id-123", 10) - - datasetCopy := []map[string]interface{}{} - - for _, datum := range jfDataset { - datum["_groupId"] = fmt.Sprintf("%v_zz2", datum["_groupId"]) - datum["_userId"] = fmt.Sprintf("%v_99y", datum["_userId"]) - datasetCopy = append(datasetCopy, datum) - } - - changes, err := utils.CompareDatasets(jfDataset, datasetCopy, false) - Expect(err).To(BeNil()) - Expect(changes).To(BeEmpty()) - }) - }) From 9206307a90b1dff9851e49c37039ad2afa669adc Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 9 Jul 2024 11:02:42 +1200 Subject: [PATCH 345/413] allow basal suspend to have no upper bound --- data/types/basal/suspend/suspend.go | 9 +- data/types/basal/suspend/suspend_test.go | 122 +++-------------------- 2 files changed, 18 insertions(+), 113 deletions(-) diff --git a/data/types/basal/suspend/suspend.go b/data/types/basal/suspend/suspend.go index f87e742ece..82bcf5c2fb 100644 --- a/data/types/basal/suspend/suspend.go +++ b/data/types/basal/suspend/suspend.go @@ -13,7 +13,6 @@ import ( const ( DeliveryType = "suspend" // TODO: Rename Type to "basal/suspended"; remove DeliveryType - DurationMaximum = 604800000 DurationMinimum = 0 ) @@ -60,12 +59,12 @@ func (s *Suspend) Validate(validator structure.Validator) { validator.String("deliveryType", &s.DeliveryType).EqualTo(DeliveryType) } - validator.Int("duration", s.Duration).Exists().InRange(DurationMinimum, DurationMaximum) + validator.Int("duration", s.Duration).Exists().GreaterThanOrEqualTo(DurationMinimum) expectedDurationValidator := validator.Int("expectedDuration", s.DurationExpected) - if s.Duration != nil && *s.Duration >= DurationMinimum && *s.Duration <= DurationMaximum { - expectedDurationValidator.InRange(*s.Duration, DurationMaximum) + if s.Duration != nil && *s.Duration >= DurationMinimum { + expectedDurationValidator.GreaterThanOrEqualTo(*s.Duration) } else { - expectedDurationValidator.InRange(DurationMinimum, DurationMaximum) + expectedDurationValidator.GreaterThanOrEqualTo(DurationMinimum) } validateSuppressed(validator.WithReference("suppressed"), s.Suppressed) } diff --git a/data/types/basal/suspend/suspend_test.go b/data/types/basal/suspend/suspend_test.go index a15d06eec4..5ee2da03ae 100644 --- a/data/types/basal/suspend/suspend_test.go +++ b/data/types/basal/suspend/suspend_test.go @@ -1,6 +1,8 @@ package suspend_test import ( + "math" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -33,8 +35,8 @@ func NewSuspend() *suspend.Suspend { datum := suspend.New() datum.Basal = *dataTypesBasalTest.RandomBasal() datum.DeliveryType = "suspend" - datum.Duration = pointer.FromInt(test.RandomIntFromRange(suspend.DurationMinimum, suspend.DurationMaximum)) - datum.DurationExpected = pointer.FromInt(test.RandomIntFromRange(*datum.Duration, suspend.DurationMaximum)) + datum.Duration = pointer.FromInt(test.RandomIntFromRange(suspend.DurationMinimum, math.MaxInt32)) + datum.DurationExpected = pointer.FromInt(test.RandomIntFromRange(*datum.Duration, math.MaxInt32)) datum.Suppressed = dataTypesBasalTemporaryTest.RandomSuppressedTemporary(dataTypesBasalScheduledTest.RandomSuppressedScheduled()) return datum } @@ -65,10 +67,6 @@ var _ = Describe("Suspend", func() { Expect(suspend.DeliveryType).To(Equal("suspend")) }) - It("DurationMaximum is expected", func() { - Expect(suspend.DurationMaximum).To(Equal(604800000)) - }) - It("DurationMinimum is expected", func() { Expect(suspend.DurationMinimum).To(Equal(0)) }) @@ -135,7 +133,7 @@ var _ = Describe("Suspend", func() { datum.DurationExpected = pointer.FromInt(-1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotGreaterThanOrEqualTo(-1, 0), "/expectedDuration", NewMeta()), ), Entry("duration missing; duration expected in range (lower)", func(datum *suspend.Suspend) { @@ -144,57 +142,48 @@ var _ = Describe("Suspend", func() { }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", NewMeta()), ), - Entry("duration missing; duration expected in range (upper)", - func(datum *suspend.Suspend) { - datum.Duration = nil - datum.DurationExpected = pointer.FromInt(604800000) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", NewMeta()), - ), - Entry("duration missing; duration expected out of range (upper)", + Entry("duration missing;", func(datum *suspend.Suspend) { datum.Duration = nil datum.DurationExpected = pointer.FromInt(604800001) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604800001, 0, 604800000), "/expectedDuration", NewMeta()), ), Entry("duration out of range (lower); duration expected missing", func(datum *suspend.Suspend) { datum.Duration = pointer.FromInt(-1) datum.DurationExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotGreaterThanOrEqualTo(-1, 0), "/duration", NewMeta()), ), Entry("duration out of range (lower); duration expected out of range (lower)", func(datum *suspend.Suspend) { datum.Duration = pointer.FromInt(-1) datum.DurationExpected = pointer.FromInt(-1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotGreaterThanOrEqualTo(-1, 0), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotGreaterThanOrEqualTo(-1, 0), "/expectedDuration", NewMeta()), ), Entry("duration out of range (lower); duration expected in range (lower)", func(datum *suspend.Suspend) { datum.Duration = pointer.FromInt(-1) datum.DurationExpected = pointer.FromInt(0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotGreaterThanOrEqualTo(-1, 0), "/duration", NewMeta()), ), Entry("duration out of range (lower); duration expected in range (upper)", func(datum *suspend.Suspend) { datum.Duration = pointer.FromInt(-1) datum.DurationExpected = pointer.FromInt(604800000) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotGreaterThanOrEqualTo(-1, 0), "/duration", NewMeta()), ), - Entry("duration out of range (lower); duration expected out of range (upper)", + Entry("duration out of range (lower); duration expected in range (upper)", func(datum *suspend.Suspend) { datum.Duration = pointer.FromInt(-1) datum.DurationExpected = pointer.FromInt(604800001) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604800001, 0, 604800000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotGreaterThanOrEqualTo(-1, 0), "/duration", NewMeta()), ), Entry("duration in range (lower); duration expected missing", func(datum *suspend.Suspend) { @@ -207,7 +196,7 @@ var _ = Describe("Suspend", func() { datum.Duration = pointer.FromInt(0) datum.DurationExpected = pointer.FromInt(-1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotGreaterThanOrEqualTo(-1, 0), "/expectedDuration", NewMeta()), ), Entry("duration in range (lower); duration expected in range (lower)", func(datum *suspend.Suspend) { @@ -215,88 +204,6 @@ var _ = Describe("Suspend", func() { datum.DurationExpected = pointer.FromInt(0) }, ), - Entry("duration in range (lower); duration expected in range (upper)", - func(datum *suspend.Suspend) { - datum.Duration = pointer.FromInt(0) - datum.DurationExpected = pointer.FromInt(604800000) - }, - ), - Entry("duration in range (lower); duration expected out of range (upper)", - func(datum *suspend.Suspend) { - datum.Duration = pointer.FromInt(0) - datum.DurationExpected = pointer.FromInt(604800001) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604800001, 0, 604800000), "/expectedDuration", NewMeta()), - ), - Entry("duration in range (upper); duration expected missing", - func(datum *suspend.Suspend) { - datum.Duration = pointer.FromInt(604800000) - datum.DurationExpected = nil - }, - ), - Entry("duration in range (upper); duration expected out of range (lower)", - func(datum *suspend.Suspend) { - datum.Duration = pointer.FromInt(604800000) - datum.DurationExpected = pointer.FromInt(604799999) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604799999, 604800000, 604800000), "/expectedDuration", NewMeta()), - ), - Entry("duration in range (upper); duration expected in range (lower)", - func(datum *suspend.Suspend) { - datum.Duration = pointer.FromInt(604800000) - datum.DurationExpected = pointer.FromInt(604800000) - }, - ), - Entry("duration in range (upper); duration expected in range (upper)", - func(datum *suspend.Suspend) { - datum.Duration = pointer.FromInt(604800000) - datum.DurationExpected = pointer.FromInt(604800000) - }, - ), - Entry("duration in range (upper); duration expected out of range (upper)", - func(datum *suspend.Suspend) { - datum.Duration = pointer.FromInt(604800000) - datum.DurationExpected = pointer.FromInt(604800001) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604800001, 604800000, 604800000), "/expectedDuration", NewMeta()), - ), - Entry("duration out of range (upper); duration expected missing", - func(datum *suspend.Suspend) { - datum.Duration = pointer.FromInt(604800001) - datum.DurationExpected = nil - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604800001, 0, 604800000), "/duration", NewMeta()), - ), - Entry("duration out of range (upper); duration expected out of range (lower)", - func(datum *suspend.Suspend) { - datum.Duration = pointer.FromInt(604800001) - datum.DurationExpected = pointer.FromInt(-1) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604800001, 0, 604800000), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/expectedDuration", NewMeta()), - ), - Entry("duration out of range (upper); duration expected in range (lower)", - func(datum *suspend.Suspend) { - datum.Duration = pointer.FromInt(604800001) - datum.DurationExpected = pointer.FromInt(0) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604800001, 0, 604800000), "/duration", NewMeta()), - ), - Entry("duration out of range (upper); duration expected in range (upper)", - func(datum *suspend.Suspend) { - datum.Duration = pointer.FromInt(604800001) - datum.DurationExpected = pointer.FromInt(604800000) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604800001, 0, 604800000), "/duration", NewMeta()), - ), - Entry("duration out of range (upper); duration expected out of range (upper)", - func(datum *suspend.Suspend) { - datum.Duration = pointer.FromInt(604800001) - datum.DurationExpected = pointer.FromInt(604800001) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604800001, 0, 604800000), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604800001, 0, 604800000), "/expectedDuration", NewMeta()), - ), Entry("suppressed missing", func(datum *suspend.Suspend) { datum.Suppressed = nil }, ), @@ -342,7 +249,6 @@ var _ = Describe("Suspend", func() { errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidType", "basal"), "/type", &basal.Meta{Type: "invalidType", DeliveryType: "invalidDeliveryType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidDeliveryType", "suspend"), "/deliveryType", &basal.Meta{Type: "invalidType", DeliveryType: "invalidDeliveryType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", &basal.Meta{Type: "invalidType", DeliveryType: "invalidDeliveryType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604800001, 0, 604800000), "/expectedDuration", &basal.Meta{Type: "invalidType", DeliveryType: "invalidDeliveryType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotValid(), "/suppressed/suppressed", &basal.Meta{Type: "invalidType", DeliveryType: "invalidDeliveryType"}), ), ) From 2828e2f003050cdf816a70faaef3aae7e2d385c0 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 10 Jul 2024 14:27:05 +1200 Subject: [PATCH 346/413] cleanup LegacyIDFields setup --- data/types/activity/physical/physical.go | 6 +- data/types/basal/basal.go | 7 +- data/types/base.go | 60 ++++++------------ data/types/base_test.go | 81 ++++++------------------ data/types/blood/blood.go | 6 +- data/types/bolus/bolus.go | 7 +- data/types/device/device.go | 7 +- data/types/food/food.go | 6 +- data/types/insulin/insulin.go | 6 +- data/types/settings/cgm/cgm.go | 6 +- 10 files changed, 82 insertions(+), 110 deletions(-) diff --git a/data/types/activity/physical/physical.go b/data/types/activity/physical/physical.go index f8951ec655..1428a91093 100644 --- a/data/types/activity/physical/physical.go +++ b/data/types/activity/physical/physical.go @@ -298,5 +298,9 @@ func (p *Physical) Normalize(normalizer data.Normalizer) { } func (p *Physical) LegacyIdentityFields() ([]string, error) { - return types.GetLegacyIdentityFields(&p.Base, types.TypeDeviceIDTimeFormat, nil) + return types.GetLegacyIDFields( + types.LegacyIDField{Name: "type", Value: &p.Type}, + types.LegacyIDField{Name: "device id", Value: p.DeviceID}, + types.GetLegacyTimeField(p.Time), + ) } diff --git a/data/types/basal/basal.go b/data/types/basal/basal.go index 749c89653b..aae4f04ae5 100644 --- a/data/types/basal/basal.go +++ b/data/types/basal/basal.go @@ -64,7 +64,12 @@ func (b *Basal) IdentityFields() ([]string, error) { } func (b *Basal) LegacyIdentityFields() ([]string, error) { - return types.GetLegacyIdentityFields(&b.Base, types.TypeDeviceIDTimeFormat, &types.LegacyIdentityCustomField{Value: b.DeliveryType, Name: "delivery type"}) + return types.GetLegacyIDFields( + types.LegacyIDField{Name: "type", Value: &b.Type}, + types.LegacyIDField{Name: "delivery type", Value: &b.DeliveryType}, + types.LegacyIDField{Name: "device id", Value: b.DeviceID}, + types.GetLegacyTimeField(b.Time), + ) } func ParseDeliveryType(parser structure.ObjectParser) *string { diff --git a/data/types/base.go b/data/types/base.go index 191adf7e90..3eec54c7b8 100644 --- a/data/types/base.go +++ b/data/types/base.go @@ -265,56 +265,36 @@ func (b *Base) IdentityFields() ([]string, error) { return []string{*b.UserID, *b.DeviceID, (*b.Time).Format(TimeFormat), b.Type}, nil } -type LegacyIdentityFormat int - -const ( - _ LegacyIdentityFormat = iota - TypeDeviceIDTimeFormat - TypeTimeDeviceIDFormat -) - -type LegacyIdentityCustomField struct { - Value string +type LegacyIDField struct { + Value *string Name string } -func GetLegacyIdentityFields(base *Base, format LegacyIdentityFormat, opt *LegacyIdentityCustomField) ([]string, error) { - if base.Type == "" { - return nil, errors.New("type is empty") +func GetLegacyTimeField(t *time.Time) LegacyIDField { + if t == nil { + return LegacyIDField{Name: "time", Value: nil} } - - if base.DeviceID == nil { - return nil, errors.New("device id is missing") + tVal := "" + if (*t).IsZero() { + return LegacyIDField{Name: "time", Value: &tVal} } - if *base.DeviceID == "" { - return nil, errors.New("device id is empty") - } - - if base.Time == nil { - return nil, errors.New("time is missing") - } - - if (*base.Time).IsZero() { - return nil, errors.New("time is empty") - } + tVal = (*t).Format(LegacyFieldTimeFormat) + return LegacyIDField{Name: "time", Value: &tVal} +} - if opt != nil { - if opt.Value == "" { - return nil, fmt.Errorf("%s is empty", opt.Name) +func GetLegacyIDFields(fields ...LegacyIDField) ([]string, error) { + identityFields := []string{} + for _, opt := range fields { + if opt.Value == nil { + return nil, fmt.Errorf("%s is missing", opt.Name) } - } - - if format == TypeDeviceIDTimeFormat { - if opt != nil { - return []string{base.Type, opt.Value, *base.DeviceID, (*base.Time).Format(LegacyFieldTimeFormat)}, nil + if *opt.Value == "" { + return nil, fmt.Errorf("%s is empty", opt.Name) } - return []string{base.Type, *base.DeviceID, (*base.Time).Format(LegacyFieldTimeFormat)}, nil - } - if opt != nil { - return []string{base.Type, opt.Value, (*base.Time).Format(LegacyFieldTimeFormat), *base.DeviceID}, nil + identityFields = append(identityFields, *opt.Value) } - return []string{base.Type, (*base.Time).Format(LegacyFieldTimeFormat), *base.DeviceID}, nil + return identityFields, nil } func (b *Base) LegacyIdentityFields() ([]string, error) { diff --git a/data/types/base_test.go b/data/types/base_test.go index 6633093c35..aaecaa3b4b 100644 --- a/data/types/base_test.go +++ b/data/types/base_test.go @@ -975,75 +975,32 @@ var _ = Describe("Base", func() { }) It("returns error if not implemented", func() { - identityFields, err := datum.LegacyIdentityFields() + legacyIDFields, err := datum.LegacyIdentityFields() Expect(err).To(MatchError("function must be implemented on data type")) - Expect(identityFields).To(BeEmpty()) + Expect(legacyIDFields).To(BeEmpty()) }) - Context("GetLegacyIdentityFields", func() { - - It("returns error if type is empty", func() { - datum.Type = "" - identityFields, err := types.GetLegacyIdentityFields(datum, types.TypeTimeDeviceIDFormat, nil) - Expect(err).To(MatchError("type is empty")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if device id is missing", func() { - datum.DeviceID = nil - identityFields, err := types.GetLegacyIdentityFields(datum, types.TypeTimeDeviceIDFormat, nil) - Expect(err).To(MatchError("device id is missing")) - Expect(identityFields).To(BeEmpty()) + Context("GetLegacyIDFields", func() { + It("returns error if value is empty", func() { + legacyIDFields, err := types.GetLegacyIDFields(types.LegacyIDField{Name: "first field", Value: pointer.FromString("")}) + Expect(err).To(MatchError("first field is empty")) + Expect(legacyIDFields).To(BeEmpty()) }) - It("returns error if device id is empty", func() { - datum.DeviceID = pointer.FromString("") - identityFields, err := types.GetLegacyIdentityFields(datum, types.TypeTimeDeviceIDFormat, nil) - Expect(err).To(MatchError("device id is empty")) - Expect(identityFields).To(BeEmpty()) + It("returns legacy id fields if valid", func() { + legacyIDFields, err := types.GetLegacyIDFields(types.LegacyIDField{Name: "first field", Value: pointer.FromString("some-thing")}) + Expect(err).To(BeNil()) + Expect(legacyIDFields).To(Equal([]string{"some-thing"})) }) - It("returns error if time is missing", func() { - datum.Time = nil - identityFields, err := types.GetLegacyIdentityFields(datum, types.TypeTimeDeviceIDFormat, nil) - Expect(err).To(MatchError("time is missing")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if time is empty", func() { - datum.Time = &time.Time{} - identityFields, err := types.GetLegacyIdentityFields(datum, types.TypeTimeDeviceIDFormat, nil) - Expect(err).To(MatchError("time is empty")) - Expect(identityFields).To(BeEmpty()) - }) - - It("returns error if extra is empty", func() { - identityFields, err := types.GetLegacyIdentityFields(datum, types.TypeTimeDeviceIDFormat, &types.LegacyIdentityCustomField{Value: "", Name: "delivery type"}) - Expect(err).To(MatchError("delivery type is empty")) - Expect(identityFields).To(BeEmpty()) - }) - - Context("with TypeDeviceIDTimeFormat", func() { - It("returns the expected legacy identity fields", func() { - identityFields, err := types.GetLegacyIdentityFields(datum, types.TypeDeviceIDTimeFormat, nil) - Expect(err).ToNot(HaveOccurred()) - Expect(identityFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat)})) - }) - }) - - Context("with TypeTimeDeviceIDFormat", func() { - It("returns the expected legacy identity fields", func() { - identityFields, err := types.GetLegacyIdentityFields(datum, types.TypeTimeDeviceIDFormat, nil) - Expect(err).ToNot(HaveOccurred()) - Expect(identityFields).To(Equal([]string{datum.Type, (*datum.Time).Format(types.LegacyFieldTimeFormat), *datum.DeviceID})) - }) - }) - Context("with LegacyIdentityCustomField", func() { - It("returns the expected legacy identity fields", func() { - identityFields, err := types.GetLegacyIdentityFields(datum, types.TypeTimeDeviceIDFormat, &types.LegacyIdentityCustomField{Value: "some-sub-type", Name: "sub type"}) - Expect(err).ToNot(HaveOccurred()) - Expect(identityFields).To(Equal([]string{datum.Type, "some-sub-type", (*datum.Time).Format(types.LegacyFieldTimeFormat), *datum.DeviceID})) - }) + It("returns legacy id with all fields if valid", func() { + legacyIDFields, err := types.GetLegacyIDFields( + types.LegacyIDField{Name: "first field", Value: pointer.FromString("one")}, + types.LegacyIDField{Name: "second field", Value: pointer.FromString("two")}, + types.LegacyIDField{Name: "third field", Value: pointer.FromString("three")}, + ) + Expect(err).To(BeNil()) + Expect(legacyIDFields).To(Equal([]string{"one", "two", "three"})) }) }) }) diff --git a/data/types/blood/blood.go b/data/types/blood/blood.go index 16fea31116..8c8e0af568 100644 --- a/data/types/blood/blood.go +++ b/data/types/blood/blood.go @@ -45,5 +45,9 @@ func (b *Blood) IdentityFields() ([]string, error) { } func (b *Blood) LegacyIdentityFields() ([]string, error) { - return types.GetLegacyIdentityFields(&b.Base, types.TypeDeviceIDTimeFormat, nil) + return types.GetLegacyIDFields( + types.LegacyIDField{Name: "type", Value: &b.Type}, + types.LegacyIDField{Name: "device id", Value: b.DeviceID}, + types.GetLegacyTimeField(b.Time), + ) } diff --git a/data/types/bolus/bolus.go b/data/types/bolus/bolus.go index 3a13b20dc2..6a0d550b97 100644 --- a/data/types/bolus/bolus.go +++ b/data/types/bolus/bolus.go @@ -95,5 +95,10 @@ func (b *Bolus) IdentityFields() ([]string, error) { } func (b *Bolus) LegacyIdentityFields() ([]string, error) { - return types.GetLegacyIdentityFields(&b.Base, types.TypeDeviceIDTimeFormat, &types.LegacyIdentityCustomField{Value: b.SubType, Name: "sub type"}) + return types.GetLegacyIDFields( + types.LegacyIDField{Name: "type", Value: &b.Type}, + types.LegacyIDField{Name: "sub type", Value: &b.SubType}, + types.LegacyIDField{Name: "device id", Value: b.DeviceID}, + types.GetLegacyTimeField(b.Time), + ) } diff --git a/data/types/device/device.go b/data/types/device/device.go index 98ca37b775..6dab185b2b 100644 --- a/data/types/device/device.go +++ b/data/types/device/device.go @@ -59,5 +59,10 @@ func (d *Device) IdentityFields() ([]string, error) { } func (d *Device) LegacyIdentityFields() ([]string, error) { - return types.GetLegacyIdentityFields(&d.Base, types.TypeTimeDeviceIDFormat, &types.LegacyIdentityCustomField{Value: d.SubType, Name: "sub type"}) + return types.GetLegacyIDFields( + types.LegacyIDField{Name: "type", Value: &d.Type}, + types.LegacyIDField{Name: "sub type", Value: &d.SubType}, + types.GetLegacyTimeField(d.Time), + types.LegacyIDField{Name: "device id", Value: d.DeviceID}, + ) } diff --git a/data/types/food/food.go b/data/types/food/food.go index 8ed96720ee..b31018c715 100644 --- a/data/types/food/food.go +++ b/data/types/food/food.go @@ -106,5 +106,9 @@ func (f *Food) Normalize(normalizer data.Normalizer) { } func (f *Food) LegacyIdentityFields() ([]string, error) { - return types.GetLegacyIdentityFields(&f.Base, types.TypeDeviceIDTimeFormat, nil) + return types.GetLegacyIDFields( + types.LegacyIDField{Name: "type", Value: &f.Type}, + types.LegacyIDField{Name: "device id", Value: f.DeviceID}, + types.GetLegacyTimeField(f.Time), + ) } diff --git a/data/types/insulin/insulin.go b/data/types/insulin/insulin.go index 0c810d95ba..83bf185fbe 100644 --- a/data/types/insulin/insulin.go +++ b/data/types/insulin/insulin.go @@ -74,5 +74,9 @@ func (i *Insulin) Normalize(normalizer data.Normalizer) { } func (i *Insulin) LegacyIdentityFields() ([]string, error) { - return types.GetLegacyIdentityFields(&i.Base, types.TypeDeviceIDTimeFormat, nil) + return types.GetLegacyIDFields( + types.LegacyIDField{Name: "type", Value: &i.Type}, + types.LegacyIDField{Name: "device id", Value: i.DeviceID}, + types.GetLegacyTimeField(i.Time), + ) } diff --git a/data/types/settings/cgm/cgm.go b/data/types/settings/cgm/cgm.go index becc27ac44..4ae7eab0f5 100644 --- a/data/types/settings/cgm/cgm.go +++ b/data/types/settings/cgm/cgm.go @@ -157,7 +157,11 @@ func (c *CGM) Normalize(normalizer data.Normalizer) { } func (c *CGM) LegacyIdentityFields() ([]string, error) { - return dataTypes.GetLegacyIdentityFields(&c.Base, dataTypes.TypeTimeDeviceIDFormat, nil) + return dataTypes.GetLegacyIDFields( + dataTypes.LegacyIDField{Name: "type", Value: &c.Type}, + dataTypes.GetLegacyTimeField(c.Time), + dataTypes.LegacyIDField{Name: "device id", Value: c.DeviceID}, + ) } func IsValidTransmitterID(value string) bool { From 8a63758833719887b6f09ed785a4376d9a051dae Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 11 Jul 2024 08:28:55 +1200 Subject: [PATCH 347/413] expand device list --- .../deduplicator/device_deactivate_hash.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index ebf50dffc8..6eb70974cb 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -28,9 +28,15 @@ var DeviceDeactivateHashDeviceManufacturerDeviceModels = map[string][]string{ } var DeviceDeactivateLegacyHasheManufacturerDeviceModels = map[string][]string{ - "Tandem": {"T:Slim"}, - "Insulet": {"Dash", "Eros"}, - //TODO: other devices here + "Arkray": {"GlucocardExpression"}, + "Bayer": {"Contour Next Link", "Contour Next Link 2.4", "Contour Next", "Contour USB", "Contour Next USB", "Contour Next One", "Contour", "Contour Next EZ", "Contour Plus", "Contour Plus Blue"}, + "Dexcom": {"G5 touchscreen receiver", "G6 touchscreen receiver"}, + "GlucoRx": {"Nexus", "HCT", "Nexus Mini Ultra", "Go"}, + "Insulet": {"Dash", "Eros"}, + "i-SENS": {"CareSens"}, + "MicroTech": {"Equil"}, + "Roche": {"Aviva Connect", "Performa Connect", "Guide", "Instant (single-button)", "Guide Me", "Instant (two-button)", "Instant S (single-button)", "ReliOn Platinum"}, + "Tandem": {"T:Slim"}, } type DeviceDeactivateHash struct { From 4218656b7a0d20c98c8c943cfa446e7a0598d813 Mon Sep 17 00:00:00 2001 From: Jamie Bate Date: Fri, 12 Jul 2024 09:00:55 +1200 Subject: [PATCH 348/413] have generic raw object for units and value (#749) * have generic raw object for units and value * formatting * review cleanup --- data/blood/glucose/glucose.go | 11 ++++ data/blood/glucose/glucose_test.go | 24 ++++++++ data/blood/glucose/test/glucose.go | 21 +++++++ data/types/blood/blood.go | 49 ++++++++++++++- .../glucose/selfmonitored/selfmonitored.go | 18 +++--- .../selfmonitored/selfmonitored_test.go | 61 +++++++++++++++---- data/types/blood/test/blood.go | 2 + 7 files changed, 164 insertions(+), 22 deletions(-) diff --git a/data/blood/glucose/glucose.go b/data/blood/glucose/glucose.go index 32ca889dd9..33ac5d3f99 100644 --- a/data/blood/glucose/glucose.go +++ b/data/blood/glucose/glucose.go @@ -67,3 +67,14 @@ func NormalizeValueForUnits(value *float64, units *string) *float64 { } return value } + +func NormalizeValueForUnitsWithFullPrecision(value *float64, units *string) *float64 { + if value != nil && units != nil { + switch *units { + case MgdL, Mgdl: + floatValue := *value / MmolLToMgdLConversionFactor + return &floatValue + } + } + return value +} diff --git a/data/blood/glucose/glucose_test.go b/data/blood/glucose/glucose_test.go index cf726fd967..f61942a14b 100644 --- a/data/blood/glucose/glucose_test.go +++ b/data/blood/glucose/glucose_test.go @@ -125,4 +125,28 @@ var _ = Describe("Glucose", func() { } }) }) + Context("NormalizeValueForUnitsWithFullPrecision", func() { + DescribeTable("given value and units", + func(value *float64, units *string, expectedValue *float64) { + actualValue := glucose.NormalizeValueForUnitsWithFullPrecision(value, units) + if expectedValue == nil { + Expect(actualValue).To(BeNil()) + } else { + Expect(actualValue).ToNot(BeNil()) + Expect(*actualValue).To(Equal(*expectedValue)) + } + }, + Entry("returns nil for nil value", nil, pointer.FromString("mmol/L"), nil), + Entry("returns unchanged value for nil units", pointer.FromFloat64(10.0), nil, pointer.FromFloat64(10.0)), + Entry("returns unchanged value for unknown units", pointer.FromFloat64(10.0), pointer.FromString("unknown"), pointer.FromFloat64(10.0)), + Entry("returns unchanged value for mmol/L units", pointer.FromFloat64(10.0), pointer.FromString("mmol/L"), pointer.FromFloat64(10.0)), + Entry("returns unchanged value for mmol/l units", pointer.FromFloat64(10.0), pointer.FromString("mmol/l"), pointer.FromFloat64(10.0)), + + Entry("returns converted value for mg/dL units", pointer.FromFloat64(140.0), pointer.FromString("mg/dL"), pointer.FromFloat64(7.771047187463747)), + Entry("returns converted value for mg/dL units", pointer.FromFloat64(100.0), pointer.FromString("mg/dL"), pointer.FromFloat64(5.550747991045533)), + Entry("returns converted value for mg/dl units", pointer.FromFloat64(80.0), pointer.FromString("mg/dl"), pointer.FromFloat64(4.440598392836427)), + Entry("returns converted value for mg/dl units", pointer.FromFloat64(69.0), pointer.FromString("mg/dl"), pointer.FromFloat64(3.830016113821418)), + Entry("returns converted value for mg/dl units", pointer.FromFloat64(50.0), pointer.FromString("mg/dl"), pointer.FromFloat64(2.7753739955227665)), + ) + }) }) diff --git a/data/blood/glucose/test/glucose.go b/data/blood/glucose/test/glucose.go index d170a86666..445155ae57 100644 --- a/data/blood/glucose/test/glucose.go +++ b/data/blood/glucose/test/glucose.go @@ -1,10 +1,31 @@ package test import ( + "github.com/onsi/gomega" + dataBloodGlucose "github.com/tidepool-org/platform/data/blood/glucose" + "github.com/tidepool-org/platform/metadata" "github.com/tidepool-org/platform/test" ) func RandomUnits() string { return test.RandomStringFromArray(dataBloodGlucose.Units()) } + +func ExpectRaw(raw *metadata.Metadata, expectedRaw *metadata.Metadata) { + if expectedRaw != nil { + gomega.Expect(raw).ToNot(gomega.BeNil()) + if expectedRaw.Get("units") == nil { + gomega.Expect(raw.Get("units")).To(gomega.BeNil()) + } else { + gomega.Expect(raw.Get("units")).To(gomega.Equal(expectedRaw.Get("units"))) + } + if expectedRaw.Get("value") == nil { + gomega.Expect(raw.Get("value")).To(gomega.BeNil()) + } else { + gomega.Expect(raw.Get("value")).To(gomega.Equal(expectedRaw.Get("value"))) + } + } else { + gomega.Expect(raw).To(gomega.BeNil()) + } +} diff --git a/data/types/blood/blood.go b/data/types/blood/blood.go index 8c8e0af568..0e699284f0 100644 --- a/data/types/blood/blood.go +++ b/data/types/blood/blood.go @@ -5,14 +5,16 @@ import ( "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/errors" + "github.com/tidepool-org/platform/metadata" "github.com/tidepool-org/platform/structure" ) type Blood struct { types.Base `bson:",inline"` - Units *string `json:"units,omitempty" bson:"units,omitempty"` - Value *float64 `json:"value,omitempty" bson:"value,omitempty"` + Units *string `json:"units,omitempty" bson:"units,omitempty"` + Value *float64 `json:"value,omitempty" bson:"value,omitempty"` + Raw *metadata.Metadata `json:"raw,omitempty" bson:"raw,omitempty"` } func New(typ string) Blood { @@ -51,3 +53,46 @@ func (b *Blood) LegacyIdentityFields() ([]string, error) { types.GetLegacyTimeField(b.Time), ) } + +func (b *Blood) GetRawValueAndUnits() (*float64, *string, error) { + if b.Raw == nil { + return nil, nil, errors.New("raw data is missing") + } + + rUnits := b.Raw.Get("units") + if rUnits == nil { + return nil, nil, errors.New("raw units are missing") + } + + units, ok := rUnits.(string) + if !ok { + return nil, nil, errors.New("raw units are invalid") + } + + rValue := b.Raw.Get("value") + if rValue == nil { + return nil, nil, errors.New("raw value is missing") + } + + value, ok := rValue.(float64) + if !ok { + return nil, nil, errors.New("raw value is invalid") + } + + return &value, &units, nil + +} + +func (b *Blood) SetRawValueAndUnits(value *float64, units *string) { + if b.Raw == nil { + b.Raw = metadata.NewMetadata() + } + + if units != nil { + b.Raw.Set("units", *units) + } + + if value != nil { + b.Raw.Set("value", *value) + } +} diff --git a/data/types/blood/glucose/selfmonitored/selfmonitored.go b/data/types/blood/glucose/selfmonitored/selfmonitored.go index 5b916d0f28..f64e430a19 100644 --- a/data/types/blood/glucose/selfmonitored/selfmonitored.go +++ b/data/types/blood/glucose/selfmonitored/selfmonitored.go @@ -1,10 +1,10 @@ package selfmonitored import ( - "errors" "strconv" "github.com/tidepool-org/platform/data" + dataBloodGlucose "github.com/tidepool-org/platform/data/blood/glucose" "github.com/tidepool-org/platform/data/types/blood/glucose" "github.com/tidepool-org/platform/structure" ) @@ -66,7 +66,11 @@ func (s *SelfMonitored) Normalize(normalizer data.Normalizer) { normalizer = normalizer.WithMeta(s.Meta()) } - s.Glucose.Normalize(normalizer) + if normalizer.Origin() == structure.OriginExternal { + s.SetRawValueAndUnits(s.Value, s.Units) + s.Value = dataBloodGlucose.NormalizeValueForUnits(s.Value, s.Units) + s.Units = dataBloodGlucose.NormalizeUnits(s.Units) + } } func (s *SelfMonitored) LegacyIdentityFields() ([]string, error) { @@ -74,10 +78,10 @@ func (s *SelfMonitored) LegacyIdentityFields() ([]string, error) { if err != nil { return nil, err } - - if s.Value == nil { - return nil, errors.New("value is missing") + value, units, err := s.GetRawValueAndUnits() + if err != nil { + return nil, err } - - return append(identityFields, strconv.FormatFloat(*s.Value, 'f', -1, 64)), nil + fullPrecisionValue := dataBloodGlucose.NormalizeValueForUnitsWithFullPrecision(value, units) + return append(identityFields, strconv.FormatFloat(*fullPrecisionValue, 'f', -1, 64)), nil } diff --git a/data/types/blood/glucose/selfmonitored/selfmonitored_test.go b/data/types/blood/glucose/selfmonitored/selfmonitored_test.go index 993ddbd7c8..943cc17772 100644 --- a/data/types/blood/glucose/selfmonitored/selfmonitored_test.go +++ b/data/types/blood/glucose/selfmonitored/selfmonitored_test.go @@ -7,13 +7,17 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + dataBloodGlucose "github.com/tidepool-org/platform/data/blood/glucose" dataBloodGlucoseTest "github.com/tidepool-org/platform/data/blood/glucose/test" dataNormalizer "github.com/tidepool-org/platform/data/normalizer" "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" + "github.com/tidepool-org/platform/metadata" + dataTypesBloodGlucoseTest "github.com/tidepool-org/platform/data/types/blood/glucose/test" dataTypesTest "github.com/tidepool-org/platform/data/types/test" errorsTest "github.com/tidepool-org/platform/errors/test" + metadataTest "github.com/tidepool-org/platform/metadata/test" "github.com/tidepool-org/platform/pointer" "github.com/tidepool-org/platform/structure" structureValidator "github.com/tidepool-org/platform/structure/validator" @@ -73,6 +77,7 @@ var _ = Describe("SelfMonitored", func() { Expect(datum.Units).To(BeNil()) Expect(datum.Value).To(BeNil()) Expect(datum.SubType).To(BeNil()) + Expect(datum.Raw).To(BeNil()) }) }) @@ -298,6 +303,7 @@ var _ = Describe("SelfMonitored", func() { datum.Normalize(normalizer.WithOrigin(origin)) Expect(normalizer.Error()).To(BeNil()) Expect(normalizer.Data()).To(BeEmpty()) + expectedDatum.Raw = metadataTest.CloneMetadata(datum.Raw) if expectator != nil { expectator(datum, expectedDatum, units) } @@ -352,8 +358,9 @@ var _ = Describe("SelfMonitored", func() { ) DescribeTable("normalizes the datum with origin external", - func(units *string, mutator func(datum *selfmonitored.SelfMonitored, units *string), expectator func(datum *selfmonitored.SelfMonitored, expectedDatum *selfmonitored.SelfMonitored, units *string)) { + func(units *string, mutator func(datum *selfmonitored.SelfMonitored, units *string), expectator func(datum *selfmonitored.SelfMonitored, expectedDatum *selfmonitored.SelfMonitored, units *string, value *float64)) { datum := NewSelfMonitored(units) + originalValue := pointer.CloneFloat64(datum.Value) mutator(datum, units) expectedDatum := CloneSelfMonitored(datum) normalizer := dataNormalizer.New() @@ -361,8 +368,9 @@ var _ = Describe("SelfMonitored", func() { datum.Normalize(normalizer.WithOrigin(structure.OriginExternal)) Expect(normalizer.Error()).To(BeNil()) Expect(normalizer.Data()).To(BeEmpty()) + expectedDatum.Raw = metadataTest.CloneMetadata(datum.Raw) if expectator != nil { - expectator(datum, expectedDatum, units) + expectator(datum, expectedDatum, units, originalValue) } Expect(datum).To(Equal(expectedDatum)) }, @@ -379,45 +387,52 @@ var _ = Describe("SelfMonitored", func() { Entry("modifies the datum; units mmol/l", pointer.FromString("mmol/l"), func(datum *selfmonitored.SelfMonitored, units *string) {}, - func(datum *selfmonitored.SelfMonitored, expectedDatum *selfmonitored.SelfMonitored, units *string) { + func(datum *selfmonitored.SelfMonitored, expectedDatum *selfmonitored.SelfMonitored, units *string, value *float64) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) + dataBloodGlucoseTest.ExpectRaw(datum.Raw, &metadata.Metadata{"units": *units, "value": *value}) }, ), Entry("modifies the datum; units mmol/l; value missing", pointer.FromString("mmol/l"), func(datum *selfmonitored.SelfMonitored, units *string) { datum.Value = nil }, - func(datum *selfmonitored.SelfMonitored, expectedDatum *selfmonitored.SelfMonitored, units *string) { + func(datum *selfmonitored.SelfMonitored, expectedDatum *selfmonitored.SelfMonitored, units *string, value *float64) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) + dataBloodGlucoseTest.ExpectRaw(datum.Raw, &metadata.Metadata{"units": *units}) }, ), Entry("modifies the datum; units mg/dL", pointer.FromString("mg/dL"), func(datum *selfmonitored.SelfMonitored, units *string) {}, - func(datum *selfmonitored.SelfMonitored, expectedDatum *selfmonitored.SelfMonitored, units *string) { + func(datum *selfmonitored.SelfMonitored, expectedDatum *selfmonitored.SelfMonitored, units *string, value *float64) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) dataBloodGlucoseTest.ExpectNormalizedValue(datum.Value, expectedDatum.Value, units) + dataBloodGlucoseTest.ExpectRaw(datum.Raw, &metadata.Metadata{"units": *units, "value": *value}) }, ), Entry("modifies the datum; units mg/dL; value missing", pointer.FromString("mg/dL"), func(datum *selfmonitored.SelfMonitored, units *string) { datum.Value = nil }, - func(datum *selfmonitored.SelfMonitored, expectedDatum *selfmonitored.SelfMonitored, units *string) { + func(datum *selfmonitored.SelfMonitored, expectedDatum *selfmonitored.SelfMonitored, units *string, value *float64) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) + dataBloodGlucoseTest.ExpectRaw(datum.Raw, expectedDatum.Raw) + dataBloodGlucoseTest.ExpectRaw(datum.Raw, &metadata.Metadata{"units": *units}) }, ), Entry("modifies the datum; units mg/dl", pointer.FromString("mg/dl"), func(datum *selfmonitored.SelfMonitored, units *string) {}, - func(datum *selfmonitored.SelfMonitored, expectedDatum *selfmonitored.SelfMonitored, units *string) { + func(datum *selfmonitored.SelfMonitored, expectedDatum *selfmonitored.SelfMonitored, units *string, value *float64) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) dataBloodGlucoseTest.ExpectNormalizedValue(datum.Value, expectedDatum.Value, units) + dataBloodGlucoseTest.ExpectRaw(datum.Raw, &metadata.Metadata{"units": *units, "value": *value}) }, ), Entry("modifies the datum; units mg/dl; value missing", pointer.FromString("mg/dl"), func(datum *selfmonitored.SelfMonitored, units *string) { datum.Value = nil }, - func(datum *selfmonitored.SelfMonitored, expectedDatum *selfmonitored.SelfMonitored, units *string) { + func(datum *selfmonitored.SelfMonitored, expectedDatum *selfmonitored.SelfMonitored, units *string, value *float64) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) + dataBloodGlucoseTest.ExpectRaw(datum.Raw, &metadata.Metadata{"units": *units, "value": nil}) }, ), ) @@ -486,7 +501,10 @@ var _ = Describe("SelfMonitored", func() { var datum *selfmonitored.SelfMonitored BeforeEach(func() { - datum = NewSelfMonitored(pointer.FromString("mmol/l")) + datum = NewSelfMonitored(pointer.FromString("mg/dl")) + normalizer := dataNormalizer.New() + Expect(normalizer).ToNot(BeNil()) + datum.Normalize(normalizer.WithOrigin(structure.OriginExternal)) }) It("returns error if device id is missing", func() { @@ -517,17 +535,34 @@ var _ = Describe("SelfMonitored", func() { Expect(identityFields).To(BeEmpty()) }) - It("returns error if value is missing", func() { - datum.Value = nil + It("returns error if raw is missing", func() { + datum.Raw = nil + identityFields, err := datum.LegacyIdentityFields() + Expect(err.Error()).To(Equal("raw data is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if raw value is missing", func() { + datum.Raw.Delete("value") identityFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("value is missing")) + Expect(err.Error()).To(Equal("raw value is missing")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns error if raw units are missing", func() { + datum.Raw.Delete("units") + identityFields, err := datum.LegacyIdentityFields() + Expect(err.Error()).To(Equal("raw units are missing")) Expect(identityFields).To(BeEmpty()) }) It("returns the expected legacy identity fields", func() { legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat), strconv.FormatFloat(*datum.Value, 'f', -1, 64)})) + value, units, err := datum.GetRawValueAndUnits() + Expect(err).ToNot(HaveOccurred()) + fullPrecisionValue := dataBloodGlucose.NormalizeValueForUnitsWithFullPrecision(value, units) + Expect(legacyIdentityFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat), strconv.FormatFloat(*fullPrecisionValue, 'f', -1, 64)})) }) }) }) diff --git a/data/types/blood/test/blood.go b/data/types/blood/test/blood.go index 048b20ec54..cdb972a854 100644 --- a/data/types/blood/test/blood.go +++ b/data/types/blood/test/blood.go @@ -5,6 +5,7 @@ import ( "github.com/tidepool-org/platform/data/types/blood" dataTypesTest "github.com/tidepool-org/platform/data/types/test" + metadataTest "github.com/tidepool-org/platform/metadata/test" "github.com/tidepool-org/platform/pointer" "github.com/tidepool-org/platform/test" ) @@ -25,5 +26,6 @@ func CloneBlood(datum *blood.Blood) *blood.Blood { clone.Base = *dataTypesTest.CloneBase(&datum.Base) clone.Units = pointer.CloneString(datum.Units) clone.Value = pointer.CloneFloat64(datum.Value) + clone.Raw = metadataTest.CloneMetadata(datum.Raw) return clone } From c6ac9ad3ac07a9d724fa35ca3e86c0f66cf3b543 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 12 Jul 2024 09:54:56 +1200 Subject: [PATCH 349/413] requirement updates --- go.mod | 5 +++++ go.sum | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/go.mod b/go.mod index 2d4e7d4d7f..fbe1d31331 100644 --- a/go.mod +++ b/go.mod @@ -39,6 +39,11 @@ require ( syreclabs.com/go/faker v1.2.3 ) +require ( + github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect +) + require ( github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/avast/retry-go v3.0.0+incompatible // indirect diff --git a/go.sum b/go.sum index b2de3006c0..559fc9c597 100644 --- a/go.sum +++ b/go.sum @@ -169,6 +169,7 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -188,6 +189,10 @@ github.com/urfave/cli v1.22.15 h1:nuqt+pdC/KqswQKhETJjo7pvn/k4xMUxgW6liI7XpnM= github.com/urfave/cli v1.22.15/go.mod h1:wSan1hmo5zeyLGBjRJbzRTNk8gwoYa2B9n4q9dmRIc0= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= +github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= From 16fdcb83f47348d736b8cfdbe616425152e4333b Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 12 Jul 2024 10:36:16 +1200 Subject: [PATCH 350/413] updates for deps --- .../vmihailenco/msgpack/v5/.prettierrc | 4 + .../vmihailenco/msgpack/v5/.travis.yml | 20 + .../vmihailenco/msgpack/v5/CHANGELOG.md | 51 ++ .../github.com/vmihailenco/msgpack/v5/LICENSE | 25 + .../vmihailenco/msgpack/v5/Makefile | 6 + .../vmihailenco/msgpack/v5/README.md | 86 +++ .../msgpack/v5/commitlint.config.js | 1 + .../vmihailenco/msgpack/v5/decode.go | 663 ++++++++++++++++++ .../vmihailenco/msgpack/v5/decode_map.go | 339 +++++++++ .../vmihailenco/msgpack/v5/decode_number.go | 295 ++++++++ .../vmihailenco/msgpack/v5/decode_query.go | 158 +++++ .../vmihailenco/msgpack/v5/decode_slice.go | 191 +++++ .../vmihailenco/msgpack/v5/decode_string.go | 192 +++++ .../vmihailenco/msgpack/v5/decode_value.go | 250 +++++++ .../vmihailenco/msgpack/v5/encode.go | 269 +++++++ .../vmihailenco/msgpack/v5/encode_map.go | 179 +++++ .../vmihailenco/msgpack/v5/encode_number.go | 252 +++++++ .../vmihailenco/msgpack/v5/encode_slice.go | 139 ++++ .../vmihailenco/msgpack/v5/encode_value.go | 245 +++++++ .../github.com/vmihailenco/msgpack/v5/ext.go | 303 ++++++++ .../vmihailenco/msgpack/v5/intern.go | 238 +++++++ .../vmihailenco/msgpack/v5/msgpack.go | 52 ++ .../msgpack/v5/msgpcode/msgpcode.go | 88 +++ .../vmihailenco/msgpack/v5/package.json | 4 + .../github.com/vmihailenco/msgpack/v5/safe.go | 13 + .../github.com/vmihailenco/msgpack/v5/time.go | 145 ++++ .../vmihailenco/msgpack/v5/types.go | 407 +++++++++++ .../vmihailenco/msgpack/v5/unsafe.go | 22 + .../vmihailenco/msgpack/v5/version.go | 6 + .../vmihailenco/tagparser/v2/.travis.yml | 19 + .../vmihailenco/tagparser/v2/LICENSE | 25 + .../vmihailenco/tagparser/v2/Makefile | 9 + .../vmihailenco/tagparser/v2/README.md | 24 + .../tagparser/v2/internal/parser/parser.go | 82 +++ .../vmihailenco/tagparser/v2/internal/safe.go | 11 + .../tagparser/v2/internal/unsafe.go | 22 + .../vmihailenco/tagparser/v2/tagparser.go | 166 +++++ vendor/modules.txt | 9 + 38 files changed, 5010 insertions(+) create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/.prettierrc create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/.travis.yml create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/CHANGELOG.md create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/LICENSE create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/Makefile create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/README.md create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/commitlint.config.js create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/decode.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/decode_map.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/decode_number.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/decode_query.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/decode_slice.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/decode_string.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/decode_value.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/encode.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/encode_map.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/encode_number.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/encode_slice.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/encode_value.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/ext.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/intern.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/msgpack.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/msgpcode/msgpcode.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/package.json create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/safe.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/time.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/types.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/unsafe.go create mode 100644 vendor/github.com/vmihailenco/msgpack/v5/version.go create mode 100644 vendor/github.com/vmihailenco/tagparser/v2/.travis.yml create mode 100644 vendor/github.com/vmihailenco/tagparser/v2/LICENSE create mode 100644 vendor/github.com/vmihailenco/tagparser/v2/Makefile create mode 100644 vendor/github.com/vmihailenco/tagparser/v2/README.md create mode 100644 vendor/github.com/vmihailenco/tagparser/v2/internal/parser/parser.go create mode 100644 vendor/github.com/vmihailenco/tagparser/v2/internal/safe.go create mode 100644 vendor/github.com/vmihailenco/tagparser/v2/internal/unsafe.go create mode 100644 vendor/github.com/vmihailenco/tagparser/v2/tagparser.go diff --git a/vendor/github.com/vmihailenco/msgpack/v5/.prettierrc b/vendor/github.com/vmihailenco/msgpack/v5/.prettierrc new file mode 100644 index 0000000000..8b7f044ad1 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/.prettierrc @@ -0,0 +1,4 @@ +semi: false +singleQuote: true +proseWrap: always +printWidth: 100 diff --git a/vendor/github.com/vmihailenco/msgpack/v5/.travis.yml b/vendor/github.com/vmihailenco/msgpack/v5/.travis.yml new file mode 100644 index 0000000000..e2ce06c49f --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/.travis.yml @@ -0,0 +1,20 @@ +sudo: false +language: go + +go: + - 1.15.x + - 1.16.x + - tip + +matrix: + allow_failures: + - go: tip + +env: + - GO111MODULE=on + +go_import_path: github.com/vmihailenco/msgpack + +before_install: + - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go + env GOPATH)/bin v1.31.0 diff --git a/vendor/github.com/vmihailenco/msgpack/v5/CHANGELOG.md b/vendor/github.com/vmihailenco/msgpack/v5/CHANGELOG.md new file mode 100644 index 0000000000..f6b19d5ba4 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/CHANGELOG.md @@ -0,0 +1,51 @@ +## [5.3.5](https://github.com/vmihailenco/msgpack/compare/v5.3.4...v5.3.5) (2021-10-22) + + + +## v5 + +### Added + +- `DecodeMap` is split into `DecodeMap`, `DecodeTypedMap`, and `DecodeUntypedMap`. +- New msgpack extensions API. + +### Changed + +- `Reset*` functions also reset flags. +- `SetMapDecodeFunc` is renamed to `SetMapDecoder`. +- `StructAsArray` is renamed to `UseArrayEncodedStructs`. +- `SortMapKeys` is renamed to `SetSortMapKeys`. + +### Removed + +- `UseJSONTag` is removed. Use `SetCustomStructTag("json")` instead. + +## v4 + +- Encode, Decode, Marshal, and Unmarshal are changed to accept single argument. EncodeMulti and + DecodeMulti are added as replacement. +- Added EncodeInt8/16/32/64 and EncodeUint8/16/32/64. +- Encoder changed to preserve type of numbers instead of chosing most compact encoding. The old + behavior can be achieved with Encoder.UseCompactEncoding. + +## v3.3 + +- `msgpack:",inline"` tag is restored to force inlining structs. + +## v3.2 + +- Decoding extension types returns pointer to the value instead of the value. Fixes #153 + +## v3 + +- gopkg.in is not supported any more. Update import path to github.com/vmihailenco/msgpack. +- Msgpack maps are decoded into map[string]interface{} by default. +- EncodeSliceLen is removed in favor of EncodeArrayLen. DecodeSliceLen is removed in favor of + DecodeArrayLen. +- Embedded structs are automatically inlined where possible. +- Time is encoded using extension as described in https://github.com/msgpack/msgpack/pull/209. Old + format is supported as well. +- EncodeInt8/16/32/64 is replaced with EncodeInt. EncodeUint8/16/32/64 is replaced with EncodeUint. + There should be no performance differences. +- DecodeInterface can now return int8/16/32 and uint8/16/32. +- PeekCode returns codes.Code instead of byte. diff --git a/vendor/github.com/vmihailenco/msgpack/v5/LICENSE b/vendor/github.com/vmihailenco/msgpack/v5/LICENSE new file mode 100644 index 0000000000..b749d07079 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) 2013 The github.com/vmihailenco/msgpack Authors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/vmihailenco/msgpack/v5/Makefile b/vendor/github.com/vmihailenco/msgpack/v5/Makefile new file mode 100644 index 0000000000..e9aade7829 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/Makefile @@ -0,0 +1,6 @@ +test: + go test ./... + go test ./... -short -race + go test ./... -run=NONE -bench=. -benchmem + env GOOS=linux GOARCH=386 go test ./... + go vet diff --git a/vendor/github.com/vmihailenco/msgpack/v5/README.md b/vendor/github.com/vmihailenco/msgpack/v5/README.md new file mode 100644 index 0000000000..66ad98b9c8 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/README.md @@ -0,0 +1,86 @@ +# MessagePack encoding for Golang + +[![Build Status](https://travis-ci.org/vmihailenco/msgpack.svg)](https://travis-ci.org/vmihailenco/msgpack) +[![PkgGoDev](https://pkg.go.dev/badge/github.com/vmihailenco/msgpack/v5)](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5) +[![Documentation](https://img.shields.io/badge/msgpack-documentation-informational)](https://msgpack.uptrace.dev/) +[![Chat](https://discordapp.com/api/guilds/752070105847955518/widget.png)](https://discord.gg/rWtp5Aj) + +> :heart: +> [**Uptrace.dev** - All-in-one tool to optimize performance and monitor errors & logs](https://uptrace.dev/?utm_source=gh-msgpack&utm_campaign=gh-msgpack-var2) + +- Join [Discord](https://discord.gg/rWtp5Aj) to ask questions. +- [Documentation](https://msgpack.uptrace.dev) +- [Reference](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5) +- [Examples](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#pkg-examples) + +Other projects you may like: + +- [Bun](https://bun.uptrace.dev) - fast and simple SQL client for PostgreSQL, MySQL, and SQLite. +- [BunRouter](https://bunrouter.uptrace.dev/) - fast and flexible HTTP router for Go. + +## Features + +- Primitives, arrays, maps, structs, time.Time and interface{}. +- Appengine \*datastore.Key and datastore.Cursor. +- [CustomEncoder]/[CustomDecoder] interfaces for custom encoding. +- [Extensions](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#example-RegisterExt) to encode + type information. +- Renaming fields via `msgpack:"my_field_name"` and alias via `msgpack:"alias:another_name"`. +- Omitting individual empty fields via `msgpack:",omitempty"` tag or all + [empty fields in a struct](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#example-Marshal-OmitEmpty). +- [Map keys sorting](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#Encoder.SetSortMapKeys). +- Encoding/decoding all + [structs as arrays](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#Encoder.UseArrayEncodedStructs) + or + [individual structs](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#example-Marshal-AsArray). +- [Encoder.SetCustomStructTag] with [Decoder.SetCustomStructTag] can turn msgpack into drop-in + replacement for any tag. +- Simple but very fast and efficient + [queries](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#example-Decoder.Query). + +[customencoder]: https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#CustomEncoder +[customdecoder]: https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#CustomDecoder +[encoder.setcustomstructtag]: + https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#Encoder.SetCustomStructTag +[decoder.setcustomstructtag]: + https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#Decoder.SetCustomStructTag + +## Installation + +msgpack supports 2 last Go versions and requires support for +[Go modules](https://github.com/golang/go/wiki/Modules). So make sure to initialize a Go module: + +```shell +go mod init github.com/my/repo +``` + +And then install msgpack/v5 (note _v5_ in the import; omitting it is a popular mistake): + +```shell +go get github.com/vmihailenco/msgpack/v5 +``` + +## Quickstart + +```go +import "github.com/vmihailenco/msgpack/v5" + +func ExampleMarshal() { + type Item struct { + Foo string + } + + b, err := msgpack.Marshal(&Item{Foo: "bar"}) + if err != nil { + panic(err) + } + + var item Item + err = msgpack.Unmarshal(b, &item) + if err != nil { + panic(err) + } + fmt.Println(item.Foo) + // Output: bar +} +``` diff --git a/vendor/github.com/vmihailenco/msgpack/v5/commitlint.config.js b/vendor/github.com/vmihailenco/msgpack/v5/commitlint.config.js new file mode 100644 index 0000000000..4fedde6daf --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/commitlint.config.js @@ -0,0 +1 @@ +module.exports = { extends: ['@commitlint/config-conventional'] } diff --git a/vendor/github.com/vmihailenco/msgpack/v5/decode.go b/vendor/github.com/vmihailenco/msgpack/v5/decode.go new file mode 100644 index 0000000000..5df40e5d9c --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/decode.go @@ -0,0 +1,663 @@ +package msgpack + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "io" + "reflect" + "sync" + "time" + + "github.com/vmihailenco/msgpack/v5/msgpcode" +) + +const ( + looseInterfaceDecodingFlag uint32 = 1 << iota + disallowUnknownFieldsFlag +) + +const ( + bytesAllocLimit = 1e6 // 1mb + sliceAllocLimit = 1e4 + maxMapSize = 1e6 +) + +type bufReader interface { + io.Reader + io.ByteScanner +} + +//------------------------------------------------------------------------------ + +var decPool = sync.Pool{ + New: func() interface{} { + return NewDecoder(nil) + }, +} + +func GetDecoder() *Decoder { + return decPool.Get().(*Decoder) +} + +func PutDecoder(dec *Decoder) { + dec.r = nil + dec.s = nil + decPool.Put(dec) +} + +//------------------------------------------------------------------------------ + +// Unmarshal decodes the MessagePack-encoded data and stores the result +// in the value pointed to by v. +func Unmarshal(data []byte, v interface{}) error { + dec := GetDecoder() + + dec.Reset(bytes.NewReader(data)) + err := dec.Decode(v) + + PutDecoder(dec) + + return err +} + +// A Decoder reads and decodes MessagePack values from an input stream. +type Decoder struct { + r io.Reader + s io.ByteScanner + buf []byte + + rec []byte // accumulates read data if not nil + + dict []string + flags uint32 + structTag string + mapDecoder func(*Decoder) (interface{}, error) +} + +// NewDecoder returns a new decoder that reads from r. +// +// The decoder introduces its own buffering and may read data from r +// beyond the requested msgpack values. Buffering can be disabled +// by passing a reader that implements io.ByteScanner interface. +func NewDecoder(r io.Reader) *Decoder { + d := new(Decoder) + d.Reset(r) + return d +} + +// Reset discards any buffered data, resets all state, and switches the buffered +// reader to read from r. +func (d *Decoder) Reset(r io.Reader) { + d.ResetDict(r, nil) +} + +// ResetDict is like Reset, but also resets the dict. +func (d *Decoder) ResetDict(r io.Reader, dict []string) { + d.resetReader(r) + d.flags = 0 + d.structTag = "" + d.mapDecoder = nil + d.dict = dict +} + +func (d *Decoder) WithDict(dict []string, fn func(*Decoder) error) error { + oldDict := d.dict + d.dict = dict + err := fn(d) + d.dict = oldDict + return err +} + +func (d *Decoder) resetReader(r io.Reader) { + if br, ok := r.(bufReader); ok { + d.r = br + d.s = br + } else { + br := bufio.NewReader(r) + d.r = br + d.s = br + } +} + +func (d *Decoder) SetMapDecoder(fn func(*Decoder) (interface{}, error)) { + d.mapDecoder = fn +} + +// UseLooseInterfaceDecoding causes decoder to use DecodeInterfaceLoose +// to decode msgpack value into Go interface{}. +func (d *Decoder) UseLooseInterfaceDecoding(on bool) { + if on { + d.flags |= looseInterfaceDecodingFlag + } else { + d.flags &= ^looseInterfaceDecodingFlag + } +} + +// SetCustomStructTag causes the decoder to use the supplied tag as a fallback option +// if there is no msgpack tag. +func (d *Decoder) SetCustomStructTag(tag string) { + d.structTag = tag +} + +// DisallowUnknownFields causes the Decoder to return an error when the destination +// is a struct and the input contains object keys which do not match any +// non-ignored, exported fields in the destination. +func (d *Decoder) DisallowUnknownFields(on bool) { + if on { + d.flags |= disallowUnknownFieldsFlag + } else { + d.flags &= ^disallowUnknownFieldsFlag + } +} + +// UseInternedStrings enables support for decoding interned strings. +func (d *Decoder) UseInternedStrings(on bool) { + if on { + d.flags |= useInternedStringsFlag + } else { + d.flags &= ^useInternedStringsFlag + } +} + +// Buffered returns a reader of the data remaining in the Decoder's buffer. +// The reader is valid until the next call to Decode. +func (d *Decoder) Buffered() io.Reader { + return d.r +} + +//nolint:gocyclo +func (d *Decoder) Decode(v interface{}) error { + var err error + switch v := v.(type) { + case *string: + if v != nil { + *v, err = d.DecodeString() + return err + } + case *[]byte: + if v != nil { + return d.decodeBytesPtr(v) + } + case *int: + if v != nil { + *v, err = d.DecodeInt() + return err + } + case *int8: + if v != nil { + *v, err = d.DecodeInt8() + return err + } + case *int16: + if v != nil { + *v, err = d.DecodeInt16() + return err + } + case *int32: + if v != nil { + *v, err = d.DecodeInt32() + return err + } + case *int64: + if v != nil { + *v, err = d.DecodeInt64() + return err + } + case *uint: + if v != nil { + *v, err = d.DecodeUint() + return err + } + case *uint8: + if v != nil { + *v, err = d.DecodeUint8() + return err + } + case *uint16: + if v != nil { + *v, err = d.DecodeUint16() + return err + } + case *uint32: + if v != nil { + *v, err = d.DecodeUint32() + return err + } + case *uint64: + if v != nil { + *v, err = d.DecodeUint64() + return err + } + case *bool: + if v != nil { + *v, err = d.DecodeBool() + return err + } + case *float32: + if v != nil { + *v, err = d.DecodeFloat32() + return err + } + case *float64: + if v != nil { + *v, err = d.DecodeFloat64() + return err + } + case *[]string: + return d.decodeStringSlicePtr(v) + case *map[string]string: + return d.decodeMapStringStringPtr(v) + case *map[string]interface{}: + return d.decodeMapStringInterfacePtr(v) + case *time.Duration: + if v != nil { + vv, err := d.DecodeInt64() + *v = time.Duration(vv) + return err + } + case *time.Time: + if v != nil { + *v, err = d.DecodeTime() + return err + } + } + + vv := reflect.ValueOf(v) + if !vv.IsValid() { + return errors.New("msgpack: Decode(nil)") + } + if vv.Kind() != reflect.Ptr { + return fmt.Errorf("msgpack: Decode(non-pointer %T)", v) + } + if vv.IsNil() { + return fmt.Errorf("msgpack: Decode(non-settable %T)", v) + } + + vv = vv.Elem() + if vv.Kind() == reflect.Interface { + if !vv.IsNil() { + vv = vv.Elem() + if vv.Kind() != reflect.Ptr { + return fmt.Errorf("msgpack: Decode(non-pointer %s)", vv.Type().String()) + } + } + } + + return d.DecodeValue(vv) +} + +func (d *Decoder) DecodeMulti(v ...interface{}) error { + for _, vv := range v { + if err := d.Decode(vv); err != nil { + return err + } + } + return nil +} + +func (d *Decoder) decodeInterfaceCond() (interface{}, error) { + if d.flags&looseInterfaceDecodingFlag != 0 { + return d.DecodeInterfaceLoose() + } + return d.DecodeInterface() +} + +func (d *Decoder) DecodeValue(v reflect.Value) error { + decode := getDecoder(v.Type()) + return decode(d, v) +} + +func (d *Decoder) DecodeNil() error { + c, err := d.readCode() + if err != nil { + return err + } + if c != msgpcode.Nil { + return fmt.Errorf("msgpack: invalid code=%x decoding nil", c) + } + return nil +} + +func (d *Decoder) decodeNilValue(v reflect.Value) error { + err := d.DecodeNil() + if v.IsNil() { + return err + } + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + v.Set(reflect.Zero(v.Type())) + return err +} + +func (d *Decoder) DecodeBool() (bool, error) { + c, err := d.readCode() + if err != nil { + return false, err + } + return d.bool(c) +} + +func (d *Decoder) bool(c byte) (bool, error) { + if c == msgpcode.Nil { + return false, nil + } + if c == msgpcode.False { + return false, nil + } + if c == msgpcode.True { + return true, nil + } + return false, fmt.Errorf("msgpack: invalid code=%x decoding bool", c) +} + +func (d *Decoder) DecodeDuration() (time.Duration, error) { + n, err := d.DecodeInt64() + if err != nil { + return 0, err + } + return time.Duration(n), nil +} + +// DecodeInterface decodes value into interface. It returns following types: +// - nil, +// - bool, +// - int8, int16, int32, int64, +// - uint8, uint16, uint32, uint64, +// - float32 and float64, +// - string, +// - []byte, +// - slices of any of the above, +// - maps of any of the above. +// +// DecodeInterface should be used only when you don't know the type of value +// you are decoding. For example, if you are decoding number it is better to use +// DecodeInt64 for negative numbers and DecodeUint64 for positive numbers. +func (d *Decoder) DecodeInterface() (interface{}, error) { + c, err := d.readCode() + if err != nil { + return nil, err + } + + if msgpcode.IsFixedNum(c) { + return int8(c), nil + } + if msgpcode.IsFixedMap(c) { + err = d.s.UnreadByte() + if err != nil { + return nil, err + } + return d.decodeMapDefault() + } + if msgpcode.IsFixedArray(c) { + return d.decodeSlice(c) + } + if msgpcode.IsFixedString(c) { + return d.string(c) + } + + switch c { + case msgpcode.Nil: + return nil, nil + case msgpcode.False, msgpcode.True: + return d.bool(c) + case msgpcode.Float: + return d.float32(c) + case msgpcode.Double: + return d.float64(c) + case msgpcode.Uint8: + return d.uint8() + case msgpcode.Uint16: + return d.uint16() + case msgpcode.Uint32: + return d.uint32() + case msgpcode.Uint64: + return d.uint64() + case msgpcode.Int8: + return d.int8() + case msgpcode.Int16: + return d.int16() + case msgpcode.Int32: + return d.int32() + case msgpcode.Int64: + return d.int64() + case msgpcode.Bin8, msgpcode.Bin16, msgpcode.Bin32: + return d.bytes(c, nil) + case msgpcode.Str8, msgpcode.Str16, msgpcode.Str32: + return d.string(c) + case msgpcode.Array16, msgpcode.Array32: + return d.decodeSlice(c) + case msgpcode.Map16, msgpcode.Map32: + err = d.s.UnreadByte() + if err != nil { + return nil, err + } + return d.decodeMapDefault() + case msgpcode.FixExt1, msgpcode.FixExt2, msgpcode.FixExt4, msgpcode.FixExt8, msgpcode.FixExt16, + msgpcode.Ext8, msgpcode.Ext16, msgpcode.Ext32: + return d.decodeInterfaceExt(c) + } + + return 0, fmt.Errorf("msgpack: unknown code %x decoding interface{}", c) +} + +// DecodeInterfaceLoose is like DecodeInterface except that: +// - int8, int16, and int32 are converted to int64, +// - uint8, uint16, and uint32 are converted to uint64, +// - float32 is converted to float64. +// - []byte is converted to string. +func (d *Decoder) DecodeInterfaceLoose() (interface{}, error) { + c, err := d.readCode() + if err != nil { + return nil, err + } + + if msgpcode.IsFixedNum(c) { + return int64(int8(c)), nil + } + if msgpcode.IsFixedMap(c) { + err = d.s.UnreadByte() + if err != nil { + return nil, err + } + return d.decodeMapDefault() + } + if msgpcode.IsFixedArray(c) { + return d.decodeSlice(c) + } + if msgpcode.IsFixedString(c) { + return d.string(c) + } + + switch c { + case msgpcode.Nil: + return nil, nil + case msgpcode.False, msgpcode.True: + return d.bool(c) + case msgpcode.Float, msgpcode.Double: + return d.float64(c) + case msgpcode.Uint8, msgpcode.Uint16, msgpcode.Uint32, msgpcode.Uint64: + return d.uint(c) + case msgpcode.Int8, msgpcode.Int16, msgpcode.Int32, msgpcode.Int64: + return d.int(c) + case msgpcode.Str8, msgpcode.Str16, msgpcode.Str32, + msgpcode.Bin8, msgpcode.Bin16, msgpcode.Bin32: + return d.string(c) + case msgpcode.Array16, msgpcode.Array32: + return d.decodeSlice(c) + case msgpcode.Map16, msgpcode.Map32: + err = d.s.UnreadByte() + if err != nil { + return nil, err + } + return d.decodeMapDefault() + case msgpcode.FixExt1, msgpcode.FixExt2, msgpcode.FixExt4, msgpcode.FixExt8, msgpcode.FixExt16, + msgpcode.Ext8, msgpcode.Ext16, msgpcode.Ext32: + return d.decodeInterfaceExt(c) + } + + return 0, fmt.Errorf("msgpack: unknown code %x decoding interface{}", c) +} + +// Skip skips next value. +func (d *Decoder) Skip() error { + c, err := d.readCode() + if err != nil { + return err + } + + if msgpcode.IsFixedNum(c) { + return nil + } + if msgpcode.IsFixedMap(c) { + return d.skipMap(c) + } + if msgpcode.IsFixedArray(c) { + return d.skipSlice(c) + } + if msgpcode.IsFixedString(c) { + return d.skipBytes(c) + } + + switch c { + case msgpcode.Nil, msgpcode.False, msgpcode.True: + return nil + case msgpcode.Uint8, msgpcode.Int8: + return d.skipN(1) + case msgpcode.Uint16, msgpcode.Int16: + return d.skipN(2) + case msgpcode.Uint32, msgpcode.Int32, msgpcode.Float: + return d.skipN(4) + case msgpcode.Uint64, msgpcode.Int64, msgpcode.Double: + return d.skipN(8) + case msgpcode.Bin8, msgpcode.Bin16, msgpcode.Bin32: + return d.skipBytes(c) + case msgpcode.Str8, msgpcode.Str16, msgpcode.Str32: + return d.skipBytes(c) + case msgpcode.Array16, msgpcode.Array32: + return d.skipSlice(c) + case msgpcode.Map16, msgpcode.Map32: + return d.skipMap(c) + case msgpcode.FixExt1, msgpcode.FixExt2, msgpcode.FixExt4, msgpcode.FixExt8, msgpcode.FixExt16, + msgpcode.Ext8, msgpcode.Ext16, msgpcode.Ext32: + return d.skipExt(c) + } + + return fmt.Errorf("msgpack: unknown code %x", c) +} + +func (d *Decoder) DecodeRaw() (RawMessage, error) { + d.rec = make([]byte, 0) + if err := d.Skip(); err != nil { + return nil, err + } + msg := RawMessage(d.rec) + d.rec = nil + return msg, nil +} + +// PeekCode returns the next MessagePack code without advancing the reader. +// Subpackage msgpack/codes defines the list of available msgpcode. +func (d *Decoder) PeekCode() (byte, error) { + c, err := d.s.ReadByte() + if err != nil { + return 0, err + } + return c, d.s.UnreadByte() +} + +// ReadFull reads exactly len(buf) bytes into the buf. +func (d *Decoder) ReadFull(buf []byte) error { + _, err := readN(d.r, buf, len(buf)) + return err +} + +func (d *Decoder) hasNilCode() bool { + code, err := d.PeekCode() + return err == nil && code == msgpcode.Nil +} + +func (d *Decoder) readCode() (byte, error) { + c, err := d.s.ReadByte() + if err != nil { + return 0, err + } + if d.rec != nil { + d.rec = append(d.rec, c) + } + return c, nil +} + +func (d *Decoder) readFull(b []byte) error { + _, err := io.ReadFull(d.r, b) + if err != nil { + return err + } + if d.rec != nil { + d.rec = append(d.rec, b...) + } + return nil +} + +func (d *Decoder) readN(n int) ([]byte, error) { + var err error + d.buf, err = readN(d.r, d.buf, n) + if err != nil { + return nil, err + } + if d.rec != nil { + // TODO: read directly into d.rec? + d.rec = append(d.rec, d.buf...) + } + return d.buf, nil +} + +func readN(r io.Reader, b []byte, n int) ([]byte, error) { + if b == nil { + if n == 0 { + return make([]byte, 0), nil + } + switch { + case n < 64: + b = make([]byte, 0, 64) + case n <= bytesAllocLimit: + b = make([]byte, 0, n) + default: + b = make([]byte, 0, bytesAllocLimit) + } + } + + if n <= cap(b) { + b = b[:n] + _, err := io.ReadFull(r, b) + return b, err + } + b = b[:cap(b)] + + var pos int + for { + alloc := min(n-len(b), bytesAllocLimit) + b = append(b, make([]byte, alloc)...) + + _, err := io.ReadFull(r, b[pos:]) + if err != nil { + return b, err + } + + if len(b) == n { + break + } + pos = len(b) + } + + return b, nil +} + +func min(a, b int) int { //nolint:unparam + if a <= b { + return a + } + return b +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/decode_map.go b/vendor/github.com/vmihailenco/msgpack/v5/decode_map.go new file mode 100644 index 0000000000..52e0526cc5 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/decode_map.go @@ -0,0 +1,339 @@ +package msgpack + +import ( + "errors" + "fmt" + "reflect" + + "github.com/vmihailenco/msgpack/v5/msgpcode" +) + +var errArrayStruct = errors.New("msgpack: number of fields in array-encoded struct has changed") + +var ( + mapStringStringPtrType = reflect.TypeOf((*map[string]string)(nil)) + mapStringStringType = mapStringStringPtrType.Elem() +) + +var ( + mapStringInterfacePtrType = reflect.TypeOf((*map[string]interface{})(nil)) + mapStringInterfaceType = mapStringInterfacePtrType.Elem() +) + +func decodeMapValue(d *Decoder, v reflect.Value) error { + n, err := d.DecodeMapLen() + if err != nil { + return err + } + + typ := v.Type() + if n == -1 { + v.Set(reflect.Zero(typ)) + return nil + } + + if v.IsNil() { + v.Set(reflect.MakeMap(typ)) + } + if n == 0 { + return nil + } + + return d.decodeTypedMapValue(v, n) +} + +func (d *Decoder) decodeMapDefault() (interface{}, error) { + if d.mapDecoder != nil { + return d.mapDecoder(d) + } + return d.DecodeMap() +} + +// DecodeMapLen decodes map length. Length is -1 when map is nil. +func (d *Decoder) DecodeMapLen() (int, error) { + c, err := d.readCode() + if err != nil { + return 0, err + } + + if msgpcode.IsExt(c) { + if err = d.skipExtHeader(c); err != nil { + return 0, err + } + + c, err = d.readCode() + if err != nil { + return 0, err + } + } + return d.mapLen(c) +} + +func (d *Decoder) mapLen(c byte) (int, error) { + if c == msgpcode.Nil { + return -1, nil + } + if c >= msgpcode.FixedMapLow && c <= msgpcode.FixedMapHigh { + return int(c & msgpcode.FixedMapMask), nil + } + if c == msgpcode.Map16 { + size, err := d.uint16() + return int(size), err + } + if c == msgpcode.Map32 { + size, err := d.uint32() + return int(size), err + } + return 0, unexpectedCodeError{code: c, hint: "map length"} +} + +func decodeMapStringStringValue(d *Decoder, v reflect.Value) error { + mptr := v.Addr().Convert(mapStringStringPtrType).Interface().(*map[string]string) + return d.decodeMapStringStringPtr(mptr) +} + +func (d *Decoder) decodeMapStringStringPtr(ptr *map[string]string) error { + size, err := d.DecodeMapLen() + if err != nil { + return err + } + if size == -1 { + *ptr = nil + return nil + } + + m := *ptr + if m == nil { + *ptr = make(map[string]string, min(size, maxMapSize)) + m = *ptr + } + + for i := 0; i < size; i++ { + mk, err := d.DecodeString() + if err != nil { + return err + } + mv, err := d.DecodeString() + if err != nil { + return err + } + m[mk] = mv + } + + return nil +} + +func decodeMapStringInterfaceValue(d *Decoder, v reflect.Value) error { + ptr := v.Addr().Convert(mapStringInterfacePtrType).Interface().(*map[string]interface{}) + return d.decodeMapStringInterfacePtr(ptr) +} + +func (d *Decoder) decodeMapStringInterfacePtr(ptr *map[string]interface{}) error { + m, err := d.DecodeMap() + if err != nil { + return err + } + *ptr = m + return nil +} + +func (d *Decoder) DecodeMap() (map[string]interface{}, error) { + n, err := d.DecodeMapLen() + if err != nil { + return nil, err + } + + if n == -1 { + return nil, nil + } + + m := make(map[string]interface{}, min(n, maxMapSize)) + + for i := 0; i < n; i++ { + mk, err := d.DecodeString() + if err != nil { + return nil, err + } + mv, err := d.decodeInterfaceCond() + if err != nil { + return nil, err + } + m[mk] = mv + } + + return m, nil +} + +func (d *Decoder) DecodeUntypedMap() (map[interface{}]interface{}, error) { + n, err := d.DecodeMapLen() + if err != nil { + return nil, err + } + + if n == -1 { + return nil, nil + } + + m := make(map[interface{}]interface{}, min(n, maxMapSize)) + + for i := 0; i < n; i++ { + mk, err := d.decodeInterfaceCond() + if err != nil { + return nil, err + } + + mv, err := d.decodeInterfaceCond() + if err != nil { + return nil, err + } + + m[mk] = mv + } + + return m, nil +} + +// DecodeTypedMap decodes a typed map. Typed map is a map that has a fixed type for keys and values. +// Key and value types may be different. +func (d *Decoder) DecodeTypedMap() (interface{}, error) { + n, err := d.DecodeMapLen() + if err != nil { + return nil, err + } + if n <= 0 { + return nil, nil + } + + key, err := d.decodeInterfaceCond() + if err != nil { + return nil, err + } + + value, err := d.decodeInterfaceCond() + if err != nil { + return nil, err + } + + keyType := reflect.TypeOf(key) + valueType := reflect.TypeOf(value) + + if !keyType.Comparable() { + return nil, fmt.Errorf("msgpack: unsupported map key: %s", keyType.String()) + } + + mapType := reflect.MapOf(keyType, valueType) + mapValue := reflect.MakeMap(mapType) + mapValue.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(value)) + + n-- + if err := d.decodeTypedMapValue(mapValue, n); err != nil { + return nil, err + } + + return mapValue.Interface(), nil +} + +func (d *Decoder) decodeTypedMapValue(v reflect.Value, n int) error { + typ := v.Type() + keyType := typ.Key() + valueType := typ.Elem() + + for i := 0; i < n; i++ { + mk := reflect.New(keyType).Elem() + if err := d.DecodeValue(mk); err != nil { + return err + } + + mv := reflect.New(valueType).Elem() + if err := d.DecodeValue(mv); err != nil { + return err + } + + v.SetMapIndex(mk, mv) + } + + return nil +} + +func (d *Decoder) skipMap(c byte) error { + n, err := d.mapLen(c) + if err != nil { + return err + } + for i := 0; i < n; i++ { + if err := d.Skip(); err != nil { + return err + } + if err := d.Skip(); err != nil { + return err + } + } + return nil +} + +func decodeStructValue(d *Decoder, v reflect.Value) error { + c, err := d.readCode() + if err != nil { + return err + } + + n, err := d.mapLen(c) + if err == nil { + return d.decodeStruct(v, n) + } + + var err2 error + n, err2 = d.arrayLen(c) + if err2 != nil { + return err + } + + if n <= 0 { + v.Set(reflect.Zero(v.Type())) + return nil + } + + fields := structs.Fields(v.Type(), d.structTag) + if n != len(fields.List) { + return errArrayStruct + } + + for _, f := range fields.List { + if err := f.DecodeValue(d, v); err != nil { + return err + } + } + + return nil +} + +func (d *Decoder) decodeStruct(v reflect.Value, n int) error { + if n == -1 { + v.Set(reflect.Zero(v.Type())) + return nil + } + + fields := structs.Fields(v.Type(), d.structTag) + for i := 0; i < n; i++ { + name, err := d.decodeStringTemp() + if err != nil { + return err + } + + if f := fields.Map[name]; f != nil { + if err := f.DecodeValue(d, v); err != nil { + return err + } + continue + } + + if d.flags&disallowUnknownFieldsFlag != 0 { + return fmt.Errorf("msgpack: unknown field %q", name) + } + if err := d.Skip(); err != nil { + return err + } + } + + return nil +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/decode_number.go b/vendor/github.com/vmihailenco/msgpack/v5/decode_number.go new file mode 100644 index 0000000000..45d6a74186 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/decode_number.go @@ -0,0 +1,295 @@ +package msgpack + +import ( + "fmt" + "math" + "reflect" + + "github.com/vmihailenco/msgpack/v5/msgpcode" +) + +func (d *Decoder) skipN(n int) error { + _, err := d.readN(n) + return err +} + +func (d *Decoder) uint8() (uint8, error) { + c, err := d.readCode() + if err != nil { + return 0, err + } + return c, nil +} + +func (d *Decoder) int8() (int8, error) { + n, err := d.uint8() + return int8(n), err +} + +func (d *Decoder) uint16() (uint16, error) { + b, err := d.readN(2) + if err != nil { + return 0, err + } + return (uint16(b[0]) << 8) | uint16(b[1]), nil +} + +func (d *Decoder) int16() (int16, error) { + n, err := d.uint16() + return int16(n), err +} + +func (d *Decoder) uint32() (uint32, error) { + b, err := d.readN(4) + if err != nil { + return 0, err + } + n := (uint32(b[0]) << 24) | + (uint32(b[1]) << 16) | + (uint32(b[2]) << 8) | + uint32(b[3]) + return n, nil +} + +func (d *Decoder) int32() (int32, error) { + n, err := d.uint32() + return int32(n), err +} + +func (d *Decoder) uint64() (uint64, error) { + b, err := d.readN(8) + if err != nil { + return 0, err + } + n := (uint64(b[0]) << 56) | + (uint64(b[1]) << 48) | + (uint64(b[2]) << 40) | + (uint64(b[3]) << 32) | + (uint64(b[4]) << 24) | + (uint64(b[5]) << 16) | + (uint64(b[6]) << 8) | + uint64(b[7]) + return n, nil +} + +func (d *Decoder) int64() (int64, error) { + n, err := d.uint64() + return int64(n), err +} + +// DecodeUint64 decodes msgpack int8/16/32/64 and uint8/16/32/64 +// into Go uint64. +func (d *Decoder) DecodeUint64() (uint64, error) { + c, err := d.readCode() + if err != nil { + return 0, err + } + return d.uint(c) +} + +func (d *Decoder) uint(c byte) (uint64, error) { + if c == msgpcode.Nil { + return 0, nil + } + if msgpcode.IsFixedNum(c) { + return uint64(int8(c)), nil + } + switch c { + case msgpcode.Uint8: + n, err := d.uint8() + return uint64(n), err + case msgpcode.Int8: + n, err := d.int8() + return uint64(n), err + case msgpcode.Uint16: + n, err := d.uint16() + return uint64(n), err + case msgpcode.Int16: + n, err := d.int16() + return uint64(n), err + case msgpcode.Uint32: + n, err := d.uint32() + return uint64(n), err + case msgpcode.Int32: + n, err := d.int32() + return uint64(n), err + case msgpcode.Uint64, msgpcode.Int64: + return d.uint64() + } + return 0, fmt.Errorf("msgpack: invalid code=%x decoding uint64", c) +} + +// DecodeInt64 decodes msgpack int8/16/32/64 and uint8/16/32/64 +// into Go int64. +func (d *Decoder) DecodeInt64() (int64, error) { + c, err := d.readCode() + if err != nil { + return 0, err + } + return d.int(c) +} + +func (d *Decoder) int(c byte) (int64, error) { + if c == msgpcode.Nil { + return 0, nil + } + if msgpcode.IsFixedNum(c) { + return int64(int8(c)), nil + } + switch c { + case msgpcode.Uint8: + n, err := d.uint8() + return int64(n), err + case msgpcode.Int8: + n, err := d.uint8() + return int64(int8(n)), err + case msgpcode.Uint16: + n, err := d.uint16() + return int64(n), err + case msgpcode.Int16: + n, err := d.uint16() + return int64(int16(n)), err + case msgpcode.Uint32: + n, err := d.uint32() + return int64(n), err + case msgpcode.Int32: + n, err := d.uint32() + return int64(int32(n)), err + case msgpcode.Uint64, msgpcode.Int64: + n, err := d.uint64() + return int64(n), err + } + return 0, fmt.Errorf("msgpack: invalid code=%x decoding int64", c) +} + +func (d *Decoder) DecodeFloat32() (float32, error) { + c, err := d.readCode() + if err != nil { + return 0, err + } + return d.float32(c) +} + +func (d *Decoder) float32(c byte) (float32, error) { + if c == msgpcode.Float { + n, err := d.uint32() + if err != nil { + return 0, err + } + return math.Float32frombits(n), nil + } + + n, err := d.int(c) + if err != nil { + return 0, fmt.Errorf("msgpack: invalid code=%x decoding float32", c) + } + return float32(n), nil +} + +// DecodeFloat64 decodes msgpack float32/64 into Go float64. +func (d *Decoder) DecodeFloat64() (float64, error) { + c, err := d.readCode() + if err != nil { + return 0, err + } + return d.float64(c) +} + +func (d *Decoder) float64(c byte) (float64, error) { + switch c { + case msgpcode.Float: + n, err := d.float32(c) + if err != nil { + return 0, err + } + return float64(n), nil + case msgpcode.Double: + n, err := d.uint64() + if err != nil { + return 0, err + } + return math.Float64frombits(n), nil + } + + n, err := d.int(c) + if err != nil { + return 0, fmt.Errorf("msgpack: invalid code=%x decoding float32", c) + } + return float64(n), nil +} + +func (d *Decoder) DecodeUint() (uint, error) { + n, err := d.DecodeUint64() + return uint(n), err +} + +func (d *Decoder) DecodeUint8() (uint8, error) { + n, err := d.DecodeUint64() + return uint8(n), err +} + +func (d *Decoder) DecodeUint16() (uint16, error) { + n, err := d.DecodeUint64() + return uint16(n), err +} + +func (d *Decoder) DecodeUint32() (uint32, error) { + n, err := d.DecodeUint64() + return uint32(n), err +} + +func (d *Decoder) DecodeInt() (int, error) { + n, err := d.DecodeInt64() + return int(n), err +} + +func (d *Decoder) DecodeInt8() (int8, error) { + n, err := d.DecodeInt64() + return int8(n), err +} + +func (d *Decoder) DecodeInt16() (int16, error) { + n, err := d.DecodeInt64() + return int16(n), err +} + +func (d *Decoder) DecodeInt32() (int32, error) { + n, err := d.DecodeInt64() + return int32(n), err +} + +func decodeFloat32Value(d *Decoder, v reflect.Value) error { + f, err := d.DecodeFloat32() + if err != nil { + return err + } + v.SetFloat(float64(f)) + return nil +} + +func decodeFloat64Value(d *Decoder, v reflect.Value) error { + f, err := d.DecodeFloat64() + if err != nil { + return err + } + v.SetFloat(f) + return nil +} + +func decodeInt64Value(d *Decoder, v reflect.Value) error { + n, err := d.DecodeInt64() + if err != nil { + return err + } + v.SetInt(n) + return nil +} + +func decodeUint64Value(d *Decoder, v reflect.Value) error { + n, err := d.DecodeUint64() + if err != nil { + return err + } + v.SetUint(n) + return nil +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/decode_query.go b/vendor/github.com/vmihailenco/msgpack/v5/decode_query.go new file mode 100644 index 0000000000..c302ed1f33 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/decode_query.go @@ -0,0 +1,158 @@ +package msgpack + +import ( + "fmt" + "strconv" + "strings" + + "github.com/vmihailenco/msgpack/v5/msgpcode" +) + +type queryResult struct { + query string + key string + hasAsterisk bool + + values []interface{} +} + +func (q *queryResult) nextKey() { + ind := strings.IndexByte(q.query, '.') + if ind == -1 { + q.key = q.query + q.query = "" + return + } + q.key = q.query[:ind] + q.query = q.query[ind+1:] +} + +// Query extracts data specified by the query from the msgpack stream skipping +// any other data. Query consists of map keys and array indexes separated with dot, +// e.g. key1.0.key2. +func (d *Decoder) Query(query string) ([]interface{}, error) { + res := queryResult{ + query: query, + } + if err := d.query(&res); err != nil { + return nil, err + } + return res.values, nil +} + +func (d *Decoder) query(q *queryResult) error { + q.nextKey() + if q.key == "" { + v, err := d.decodeInterfaceCond() + if err != nil { + return err + } + q.values = append(q.values, v) + return nil + } + + code, err := d.PeekCode() + if err != nil { + return err + } + + switch { + case code == msgpcode.Map16 || code == msgpcode.Map32 || msgpcode.IsFixedMap(code): + err = d.queryMapKey(q) + case code == msgpcode.Array16 || code == msgpcode.Array32 || msgpcode.IsFixedArray(code): + err = d.queryArrayIndex(q) + default: + err = fmt.Errorf("msgpack: unsupported code=%x decoding key=%q", code, q.key) + } + return err +} + +func (d *Decoder) queryMapKey(q *queryResult) error { + n, err := d.DecodeMapLen() + if err != nil { + return err + } + if n == -1 { + return nil + } + + for i := 0; i < n; i++ { + key, err := d.decodeStringTemp() + if err != nil { + return err + } + + if key == q.key { + if err := d.query(q); err != nil { + return err + } + if q.hasAsterisk { + return d.skipNext((n - i - 1) * 2) + } + return nil + } + + if err := d.Skip(); err != nil { + return err + } + } + + return nil +} + +func (d *Decoder) queryArrayIndex(q *queryResult) error { + n, err := d.DecodeArrayLen() + if err != nil { + return err + } + if n == -1 { + return nil + } + + if q.key == "*" { + q.hasAsterisk = true + + query := q.query + for i := 0; i < n; i++ { + q.query = query + if err := d.query(q); err != nil { + return err + } + } + + q.hasAsterisk = false + return nil + } + + ind, err := strconv.Atoi(q.key) + if err != nil { + return err + } + + for i := 0; i < n; i++ { + if i == ind { + if err := d.query(q); err != nil { + return err + } + if q.hasAsterisk { + return d.skipNext(n - i - 1) + } + return nil + } + + if err := d.Skip(); err != nil { + return err + } + } + + return nil +} + +func (d *Decoder) skipNext(n int) error { + for i := 0; i < n; i++ { + if err := d.Skip(); err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/decode_slice.go b/vendor/github.com/vmihailenco/msgpack/v5/decode_slice.go new file mode 100644 index 0000000000..db6f7c5472 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/decode_slice.go @@ -0,0 +1,191 @@ +package msgpack + +import ( + "fmt" + "reflect" + + "github.com/vmihailenco/msgpack/v5/msgpcode" +) + +var sliceStringPtrType = reflect.TypeOf((*[]string)(nil)) + +// DecodeArrayLen decodes array length. Length is -1 when array is nil. +func (d *Decoder) DecodeArrayLen() (int, error) { + c, err := d.readCode() + if err != nil { + return 0, err + } + return d.arrayLen(c) +} + +func (d *Decoder) arrayLen(c byte) (int, error) { + if c == msgpcode.Nil { + return -1, nil + } else if c >= msgpcode.FixedArrayLow && c <= msgpcode.FixedArrayHigh { + return int(c & msgpcode.FixedArrayMask), nil + } + switch c { + case msgpcode.Array16: + n, err := d.uint16() + return int(n), err + case msgpcode.Array32: + n, err := d.uint32() + return int(n), err + } + return 0, fmt.Errorf("msgpack: invalid code=%x decoding array length", c) +} + +func decodeStringSliceValue(d *Decoder, v reflect.Value) error { + ptr := v.Addr().Convert(sliceStringPtrType).Interface().(*[]string) + return d.decodeStringSlicePtr(ptr) +} + +func (d *Decoder) decodeStringSlicePtr(ptr *[]string) error { + n, err := d.DecodeArrayLen() + if err != nil { + return err + } + if n == -1 { + return nil + } + + ss := makeStrings(*ptr, n) + for i := 0; i < n; i++ { + s, err := d.DecodeString() + if err != nil { + return err + } + ss = append(ss, s) + } + *ptr = ss + + return nil +} + +func makeStrings(s []string, n int) []string { + if n > sliceAllocLimit { + n = sliceAllocLimit + } + + if s == nil { + return make([]string, 0, n) + } + + if cap(s) >= n { + return s[:0] + } + + s = s[:cap(s)] + s = append(s, make([]string, n-len(s))...) + return s[:0] +} + +func decodeSliceValue(d *Decoder, v reflect.Value) error { + n, err := d.DecodeArrayLen() + if err != nil { + return err + } + + if n == -1 { + v.Set(reflect.Zero(v.Type())) + return nil + } + if n == 0 && v.IsNil() { + v.Set(reflect.MakeSlice(v.Type(), 0, 0)) + return nil + } + + if v.Cap() >= n { + v.Set(v.Slice(0, n)) + } else if v.Len() < v.Cap() { + v.Set(v.Slice(0, v.Cap())) + } + + for i := 0; i < n; i++ { + if i >= v.Len() { + v.Set(growSliceValue(v, n)) + } + elem := v.Index(i) + if err := d.DecodeValue(elem); err != nil { + return err + } + } + + return nil +} + +func growSliceValue(v reflect.Value, n int) reflect.Value { + diff := n - v.Len() + if diff > sliceAllocLimit { + diff = sliceAllocLimit + } + v = reflect.AppendSlice(v, reflect.MakeSlice(v.Type(), diff, diff)) + return v +} + +func decodeArrayValue(d *Decoder, v reflect.Value) error { + n, err := d.DecodeArrayLen() + if err != nil { + return err + } + + if n == -1 { + return nil + } + if n > v.Len() { + return fmt.Errorf("%s len is %d, but msgpack has %d elements", v.Type(), v.Len(), n) + } + + for i := 0; i < n; i++ { + sv := v.Index(i) + if err := d.DecodeValue(sv); err != nil { + return err + } + } + + return nil +} + +func (d *Decoder) DecodeSlice() ([]interface{}, error) { + c, err := d.readCode() + if err != nil { + return nil, err + } + return d.decodeSlice(c) +} + +func (d *Decoder) decodeSlice(c byte) ([]interface{}, error) { + n, err := d.arrayLen(c) + if err != nil { + return nil, err + } + if n == -1 { + return nil, nil + } + + s := make([]interface{}, 0, min(n, sliceAllocLimit)) + for i := 0; i < n; i++ { + v, err := d.decodeInterfaceCond() + if err != nil { + return nil, err + } + s = append(s, v) + } + + return s, nil +} + +func (d *Decoder) skipSlice(c byte) error { + n, err := d.arrayLen(c) + if err != nil { + return err + } + + for i := 0; i < n; i++ { + if err := d.Skip(); err != nil { + return err + } + } + + return nil +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/decode_string.go b/vendor/github.com/vmihailenco/msgpack/v5/decode_string.go new file mode 100644 index 0000000000..e837e08bf1 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/decode_string.go @@ -0,0 +1,192 @@ +package msgpack + +import ( + "fmt" + "reflect" + + "github.com/vmihailenco/msgpack/v5/msgpcode" +) + +func (d *Decoder) bytesLen(c byte) (int, error) { + if c == msgpcode.Nil { + return -1, nil + } + + if msgpcode.IsFixedString(c) { + return int(c & msgpcode.FixedStrMask), nil + } + + switch c { + case msgpcode.Str8, msgpcode.Bin8: + n, err := d.uint8() + return int(n), err + case msgpcode.Str16, msgpcode.Bin16: + n, err := d.uint16() + return int(n), err + case msgpcode.Str32, msgpcode.Bin32: + n, err := d.uint32() + return int(n), err + } + + return 0, fmt.Errorf("msgpack: invalid code=%x decoding string/bytes length", c) +} + +func (d *Decoder) DecodeString() (string, error) { + if intern := d.flags&useInternedStringsFlag != 0; intern || len(d.dict) > 0 { + return d.decodeInternedString(intern) + } + + c, err := d.readCode() + if err != nil { + return "", err + } + return d.string(c) +} + +func (d *Decoder) string(c byte) (string, error) { + n, err := d.bytesLen(c) + if err != nil { + return "", err + } + return d.stringWithLen(n) +} + +func (d *Decoder) stringWithLen(n int) (string, error) { + if n <= 0 { + return "", nil + } + b, err := d.readN(n) + return string(b), err +} + +func decodeStringValue(d *Decoder, v reflect.Value) error { + s, err := d.DecodeString() + if err != nil { + return err + } + v.SetString(s) + return nil +} + +func (d *Decoder) DecodeBytesLen() (int, error) { + c, err := d.readCode() + if err != nil { + return 0, err + } + return d.bytesLen(c) +} + +func (d *Decoder) DecodeBytes() ([]byte, error) { + c, err := d.readCode() + if err != nil { + return nil, err + } + return d.bytes(c, nil) +} + +func (d *Decoder) bytes(c byte, b []byte) ([]byte, error) { + n, err := d.bytesLen(c) + if err != nil { + return nil, err + } + if n == -1 { + return nil, nil + } + return readN(d.r, b, n) +} + +func (d *Decoder) decodeStringTemp() (string, error) { + if intern := d.flags&useInternedStringsFlag != 0; intern || len(d.dict) > 0 { + return d.decodeInternedString(intern) + } + + c, err := d.readCode() + if err != nil { + return "", err + } + + n, err := d.bytesLen(c) + if err != nil { + return "", err + } + if n == -1 { + return "", nil + } + + b, err := d.readN(n) + if err != nil { + return "", err + } + + return bytesToString(b), nil +} + +func (d *Decoder) decodeBytesPtr(ptr *[]byte) error { + c, err := d.readCode() + if err != nil { + return err + } + return d.bytesPtr(c, ptr) +} + +func (d *Decoder) bytesPtr(c byte, ptr *[]byte) error { + n, err := d.bytesLen(c) + if err != nil { + return err + } + if n == -1 { + *ptr = nil + return nil + } + + *ptr, err = readN(d.r, *ptr, n) + return err +} + +func (d *Decoder) skipBytes(c byte) error { + n, err := d.bytesLen(c) + if err != nil { + return err + } + if n <= 0 { + return nil + } + return d.skipN(n) +} + +func decodeBytesValue(d *Decoder, v reflect.Value) error { + c, err := d.readCode() + if err != nil { + return err + } + + b, err := d.bytes(c, v.Bytes()) + if err != nil { + return err + } + + v.SetBytes(b) + + return nil +} + +func decodeByteArrayValue(d *Decoder, v reflect.Value) error { + c, err := d.readCode() + if err != nil { + return err + } + + n, err := d.bytesLen(c) + if err != nil { + return err + } + if n == -1 { + return nil + } + if n > v.Len() { + return fmt.Errorf("%s len is %d, but msgpack has %d elements", v.Type(), v.Len(), n) + } + + b := v.Slice(0, n).Bytes() + return d.readFull(b) +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/decode_value.go b/vendor/github.com/vmihailenco/msgpack/v5/decode_value.go new file mode 100644 index 0000000000..d2ff2aea50 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/decode_value.go @@ -0,0 +1,250 @@ +package msgpack + +import ( + "encoding" + "errors" + "fmt" + "reflect" +) + +var ( + interfaceType = reflect.TypeOf((*interface{})(nil)).Elem() + stringType = reflect.TypeOf((*string)(nil)).Elem() +) + +var valueDecoders []decoderFunc + +//nolint:gochecknoinits +func init() { + valueDecoders = []decoderFunc{ + reflect.Bool: decodeBoolValue, + reflect.Int: decodeInt64Value, + reflect.Int8: decodeInt64Value, + reflect.Int16: decodeInt64Value, + reflect.Int32: decodeInt64Value, + reflect.Int64: decodeInt64Value, + reflect.Uint: decodeUint64Value, + reflect.Uint8: decodeUint64Value, + reflect.Uint16: decodeUint64Value, + reflect.Uint32: decodeUint64Value, + reflect.Uint64: decodeUint64Value, + reflect.Float32: decodeFloat32Value, + reflect.Float64: decodeFloat64Value, + reflect.Complex64: decodeUnsupportedValue, + reflect.Complex128: decodeUnsupportedValue, + reflect.Array: decodeArrayValue, + reflect.Chan: decodeUnsupportedValue, + reflect.Func: decodeUnsupportedValue, + reflect.Interface: decodeInterfaceValue, + reflect.Map: decodeMapValue, + reflect.Ptr: decodeUnsupportedValue, + reflect.Slice: decodeSliceValue, + reflect.String: decodeStringValue, + reflect.Struct: decodeStructValue, + reflect.UnsafePointer: decodeUnsupportedValue, + } +} + +func getDecoder(typ reflect.Type) decoderFunc { + if v, ok := typeDecMap.Load(typ); ok { + return v.(decoderFunc) + } + fn := _getDecoder(typ) + typeDecMap.Store(typ, fn) + return fn +} + +func _getDecoder(typ reflect.Type) decoderFunc { + kind := typ.Kind() + + if kind == reflect.Ptr { + if _, ok := typeDecMap.Load(typ.Elem()); ok { + return ptrValueDecoder(typ) + } + } + + if typ.Implements(customDecoderType) { + return nilAwareDecoder(typ, decodeCustomValue) + } + if typ.Implements(unmarshalerType) { + return nilAwareDecoder(typ, unmarshalValue) + } + if typ.Implements(binaryUnmarshalerType) { + return nilAwareDecoder(typ, unmarshalBinaryValue) + } + if typ.Implements(textUnmarshalerType) { + return nilAwareDecoder(typ, unmarshalTextValue) + } + + // Addressable struct field value. + if kind != reflect.Ptr { + ptr := reflect.PtrTo(typ) + if ptr.Implements(customDecoderType) { + return addrDecoder(nilAwareDecoder(typ, decodeCustomValue)) + } + if ptr.Implements(unmarshalerType) { + return addrDecoder(nilAwareDecoder(typ, unmarshalValue)) + } + if ptr.Implements(binaryUnmarshalerType) { + return addrDecoder(nilAwareDecoder(typ, unmarshalBinaryValue)) + } + if ptr.Implements(textUnmarshalerType) { + return addrDecoder(nilAwareDecoder(typ, unmarshalTextValue)) + } + } + + switch kind { + case reflect.Ptr: + return ptrValueDecoder(typ) + case reflect.Slice: + elem := typ.Elem() + if elem.Kind() == reflect.Uint8 { + return decodeBytesValue + } + if elem == stringType { + return decodeStringSliceValue + } + case reflect.Array: + if typ.Elem().Kind() == reflect.Uint8 { + return decodeByteArrayValue + } + case reflect.Map: + if typ.Key() == stringType { + switch typ.Elem() { + case stringType: + return decodeMapStringStringValue + case interfaceType: + return decodeMapStringInterfaceValue + } + } + } + + return valueDecoders[kind] +} + +func ptrValueDecoder(typ reflect.Type) decoderFunc { + decoder := getDecoder(typ.Elem()) + return func(d *Decoder, v reflect.Value) error { + if d.hasNilCode() { + if !v.IsNil() { + v.Set(reflect.Zero(v.Type())) + } + return d.DecodeNil() + } + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + return decoder(d, v.Elem()) + } +} + +func addrDecoder(fn decoderFunc) decoderFunc { + return func(d *Decoder, v reflect.Value) error { + if !v.CanAddr() { + return fmt.Errorf("msgpack: Decode(nonaddressable %T)", v.Interface()) + } + return fn(d, v.Addr()) + } +} + +func nilAwareDecoder(typ reflect.Type, fn decoderFunc) decoderFunc { + if nilable(typ.Kind()) { + return func(d *Decoder, v reflect.Value) error { + if d.hasNilCode() { + return d.decodeNilValue(v) + } + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + return fn(d, v) + } + } + + return func(d *Decoder, v reflect.Value) error { + if d.hasNilCode() { + return d.decodeNilValue(v) + } + return fn(d, v) + } +} + +func decodeBoolValue(d *Decoder, v reflect.Value) error { + flag, err := d.DecodeBool() + if err != nil { + return err + } + v.SetBool(flag) + return nil +} + +func decodeInterfaceValue(d *Decoder, v reflect.Value) error { + if v.IsNil() { + return d.interfaceValue(v) + } + return d.DecodeValue(v.Elem()) +} + +func (d *Decoder) interfaceValue(v reflect.Value) error { + vv, err := d.decodeInterfaceCond() + if err != nil { + return err + } + + if vv != nil { + if v.Type() == errorType { + if vv, ok := vv.(string); ok { + v.Set(reflect.ValueOf(errors.New(vv))) + return nil + } + } + + v.Set(reflect.ValueOf(vv)) + } + + return nil +} + +func decodeUnsupportedValue(d *Decoder, v reflect.Value) error { + return fmt.Errorf("msgpack: Decode(unsupported %s)", v.Type()) +} + +//------------------------------------------------------------------------------ + +func decodeCustomValue(d *Decoder, v reflect.Value) error { + decoder := v.Interface().(CustomDecoder) + return decoder.DecodeMsgpack(d) +} + +func unmarshalValue(d *Decoder, v reflect.Value) error { + var b []byte + + d.rec = make([]byte, 0, 64) + if err := d.Skip(); err != nil { + return err + } + b = d.rec + d.rec = nil + + unmarshaler := v.Interface().(Unmarshaler) + return unmarshaler.UnmarshalMsgpack(b) +} + +func unmarshalBinaryValue(d *Decoder, v reflect.Value) error { + data, err := d.DecodeBytes() + if err != nil { + return err + } + + unmarshaler := v.Interface().(encoding.BinaryUnmarshaler) + return unmarshaler.UnmarshalBinary(data) +} + +func unmarshalTextValue(d *Decoder, v reflect.Value) error { + data, err := d.DecodeBytes() + if err != nil { + return err + } + + unmarshaler := v.Interface().(encoding.TextUnmarshaler) + return unmarshaler.UnmarshalText(data) +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/encode.go b/vendor/github.com/vmihailenco/msgpack/v5/encode.go new file mode 100644 index 0000000000..0ef6212e63 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/encode.go @@ -0,0 +1,269 @@ +package msgpack + +import ( + "bytes" + "io" + "reflect" + "sync" + "time" + + "github.com/vmihailenco/msgpack/v5/msgpcode" +) + +const ( + sortMapKeysFlag uint32 = 1 << iota + arrayEncodedStructsFlag + useCompactIntsFlag + useCompactFloatsFlag + useInternedStringsFlag + omitEmptyFlag +) + +type writer interface { + io.Writer + WriteByte(byte) error +} + +type byteWriter struct { + io.Writer +} + +func newByteWriter(w io.Writer) byteWriter { + return byteWriter{ + Writer: w, + } +} + +func (bw byteWriter) WriteByte(c byte) error { + _, err := bw.Write([]byte{c}) + return err +} + +//------------------------------------------------------------------------------ + +var encPool = sync.Pool{ + New: func() interface{} { + return NewEncoder(nil) + }, +} + +func GetEncoder() *Encoder { + return encPool.Get().(*Encoder) +} + +func PutEncoder(enc *Encoder) { + enc.w = nil + encPool.Put(enc) +} + +// Marshal returns the MessagePack encoding of v. +func Marshal(v interface{}) ([]byte, error) { + enc := GetEncoder() + + var buf bytes.Buffer + enc.Reset(&buf) + + err := enc.Encode(v) + b := buf.Bytes() + + PutEncoder(enc) + + if err != nil { + return nil, err + } + return b, err +} + +type Encoder struct { + w writer + + buf []byte + timeBuf []byte + + dict map[string]int + + flags uint32 + structTag string +} + +// NewEncoder returns a new encoder that writes to w. +func NewEncoder(w io.Writer) *Encoder { + e := &Encoder{ + buf: make([]byte, 9), + } + e.Reset(w) + return e +} + +// Writer returns the Encoder's writer. +func (e *Encoder) Writer() io.Writer { + return e.w +} + +// Reset discards any buffered data, resets all state, and switches the writer to write to w. +func (e *Encoder) Reset(w io.Writer) { + e.ResetDict(w, nil) +} + +// ResetDict is like Reset, but also resets the dict. +func (e *Encoder) ResetDict(w io.Writer, dict map[string]int) { + e.resetWriter(w) + e.flags = 0 + e.structTag = "" + e.dict = dict +} + +func (e *Encoder) WithDict(dict map[string]int, fn func(*Encoder) error) error { + oldDict := e.dict + e.dict = dict + err := fn(e) + e.dict = oldDict + return err +} + +func (e *Encoder) resetWriter(w io.Writer) { + if bw, ok := w.(writer); ok { + e.w = bw + } else { + e.w = newByteWriter(w) + } +} + +// SetSortMapKeys causes the Encoder to encode map keys in increasing order. +// Supported map types are: +// - map[string]string +// - map[string]interface{} +func (e *Encoder) SetSortMapKeys(on bool) *Encoder { + if on { + e.flags |= sortMapKeysFlag + } else { + e.flags &= ^sortMapKeysFlag + } + return e +} + +// SetCustomStructTag causes the Encoder to use a custom struct tag as +// fallback option if there is no msgpack tag. +func (e *Encoder) SetCustomStructTag(tag string) { + e.structTag = tag +} + +// SetOmitEmpty causes the Encoder to omit empty values by default. +func (e *Encoder) SetOmitEmpty(on bool) { + if on { + e.flags |= omitEmptyFlag + } else { + e.flags &= ^omitEmptyFlag + } +} + +// UseArrayEncodedStructs causes the Encoder to encode Go structs as msgpack arrays. +func (e *Encoder) UseArrayEncodedStructs(on bool) { + if on { + e.flags |= arrayEncodedStructsFlag + } else { + e.flags &= ^arrayEncodedStructsFlag + } +} + +// UseCompactEncoding causes the Encoder to chose the most compact encoding. +// For example, it allows to encode small Go int64 as msgpack int8 saving 7 bytes. +func (e *Encoder) UseCompactInts(on bool) { + if on { + e.flags |= useCompactIntsFlag + } else { + e.flags &= ^useCompactIntsFlag + } +} + +// UseCompactFloats causes the Encoder to chose a compact integer encoding +// for floats that can be represented as integers. +func (e *Encoder) UseCompactFloats(on bool) { + if on { + e.flags |= useCompactFloatsFlag + } else { + e.flags &= ^useCompactFloatsFlag + } +} + +// UseInternedStrings causes the Encoder to intern strings. +func (e *Encoder) UseInternedStrings(on bool) { + if on { + e.flags |= useInternedStringsFlag + } else { + e.flags &= ^useInternedStringsFlag + } +} + +func (e *Encoder) Encode(v interface{}) error { + switch v := v.(type) { + case nil: + return e.EncodeNil() + case string: + return e.EncodeString(v) + case []byte: + return e.EncodeBytes(v) + case int: + return e.EncodeInt(int64(v)) + case int64: + return e.encodeInt64Cond(v) + case uint: + return e.EncodeUint(uint64(v)) + case uint64: + return e.encodeUint64Cond(v) + case bool: + return e.EncodeBool(v) + case float32: + return e.EncodeFloat32(v) + case float64: + return e.EncodeFloat64(v) + case time.Duration: + return e.encodeInt64Cond(int64(v)) + case time.Time: + return e.EncodeTime(v) + } + return e.EncodeValue(reflect.ValueOf(v)) +} + +func (e *Encoder) EncodeMulti(v ...interface{}) error { + for _, vv := range v { + if err := e.Encode(vv); err != nil { + return err + } + } + return nil +} + +func (e *Encoder) EncodeValue(v reflect.Value) error { + fn := getEncoder(v.Type()) + return fn(e, v) +} + +func (e *Encoder) EncodeNil() error { + return e.writeCode(msgpcode.Nil) +} + +func (e *Encoder) EncodeBool(value bool) error { + if value { + return e.writeCode(msgpcode.True) + } + return e.writeCode(msgpcode.False) +} + +func (e *Encoder) EncodeDuration(d time.Duration) error { + return e.EncodeInt(int64(d)) +} + +func (e *Encoder) writeCode(c byte) error { + return e.w.WriteByte(c) +} + +func (e *Encoder) write(b []byte) error { + _, err := e.w.Write(b) + return err +} + +func (e *Encoder) writeString(s string) error { + _, err := e.w.Write(stringToBytes(s)) + return err +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/encode_map.go b/vendor/github.com/vmihailenco/msgpack/v5/encode_map.go new file mode 100644 index 0000000000..ba4c61be72 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/encode_map.go @@ -0,0 +1,179 @@ +package msgpack + +import ( + "math" + "reflect" + "sort" + + "github.com/vmihailenco/msgpack/v5/msgpcode" +) + +func encodeMapValue(e *Encoder, v reflect.Value) error { + if v.IsNil() { + return e.EncodeNil() + } + + if err := e.EncodeMapLen(v.Len()); err != nil { + return err + } + + iter := v.MapRange() + for iter.Next() { + if err := e.EncodeValue(iter.Key()); err != nil { + return err + } + if err := e.EncodeValue(iter.Value()); err != nil { + return err + } + } + + return nil +} + +func encodeMapStringStringValue(e *Encoder, v reflect.Value) error { + if v.IsNil() { + return e.EncodeNil() + } + + if err := e.EncodeMapLen(v.Len()); err != nil { + return err + } + + m := v.Convert(mapStringStringType).Interface().(map[string]string) + if e.flags&sortMapKeysFlag != 0 { + return e.encodeSortedMapStringString(m) + } + + for mk, mv := range m { + if err := e.EncodeString(mk); err != nil { + return err + } + if err := e.EncodeString(mv); err != nil { + return err + } + } + + return nil +} + +func encodeMapStringInterfaceValue(e *Encoder, v reflect.Value) error { + if v.IsNil() { + return e.EncodeNil() + } + m := v.Convert(mapStringInterfaceType).Interface().(map[string]interface{}) + if e.flags&sortMapKeysFlag != 0 { + return e.EncodeMapSorted(m) + } + return e.EncodeMap(m) +} + +func (e *Encoder) EncodeMap(m map[string]interface{}) error { + if m == nil { + return e.EncodeNil() + } + if err := e.EncodeMapLen(len(m)); err != nil { + return err + } + for mk, mv := range m { + if err := e.EncodeString(mk); err != nil { + return err + } + if err := e.Encode(mv); err != nil { + return err + } + } + return nil +} + +func (e *Encoder) EncodeMapSorted(m map[string]interface{}) error { + if m == nil { + return e.EncodeNil() + } + if err := e.EncodeMapLen(len(m)); err != nil { + return err + } + + keys := make([]string, 0, len(m)) + + for k := range m { + keys = append(keys, k) + } + + sort.Strings(keys) + + for _, k := range keys { + if err := e.EncodeString(k); err != nil { + return err + } + if err := e.Encode(m[k]); err != nil { + return err + } + } + + return nil +} + +func (e *Encoder) encodeSortedMapStringString(m map[string]string) error { + keys := make([]string, 0, len(m)) + for k := range m { + keys = append(keys, k) + } + sort.Strings(keys) + + for _, k := range keys { + err := e.EncodeString(k) + if err != nil { + return err + } + if err = e.EncodeString(m[k]); err != nil { + return err + } + } + + return nil +} + +func (e *Encoder) EncodeMapLen(l int) error { + if l < 16 { + return e.writeCode(msgpcode.FixedMapLow | byte(l)) + } + if l <= math.MaxUint16 { + return e.write2(msgpcode.Map16, uint16(l)) + } + return e.write4(msgpcode.Map32, uint32(l)) +} + +func encodeStructValue(e *Encoder, strct reflect.Value) error { + structFields := structs.Fields(strct.Type(), e.structTag) + if e.flags&arrayEncodedStructsFlag != 0 || structFields.AsArray { + return encodeStructValueAsArray(e, strct, structFields.List) + } + fields := structFields.OmitEmpty(strct, e.flags&omitEmptyFlag != 0) + + if err := e.EncodeMapLen(len(fields)); err != nil { + return err + } + + for _, f := range fields { + if err := e.EncodeString(f.name); err != nil { + return err + } + if err := f.EncodeValue(e, strct); err != nil { + return err + } + } + + return nil +} + +func encodeStructValueAsArray(e *Encoder, strct reflect.Value, fields []*field) error { + if err := e.EncodeArrayLen(len(fields)); err != nil { + return err + } + for _, f := range fields { + if err := f.EncodeValue(e, strct); err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/encode_number.go b/vendor/github.com/vmihailenco/msgpack/v5/encode_number.go new file mode 100644 index 0000000000..63c311bfae --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/encode_number.go @@ -0,0 +1,252 @@ +package msgpack + +import ( + "math" + "reflect" + + "github.com/vmihailenco/msgpack/v5/msgpcode" +) + +// EncodeUint8 encodes an uint8 in 2 bytes preserving type of the number. +func (e *Encoder) EncodeUint8(n uint8) error { + return e.write1(msgpcode.Uint8, n) +} + +func (e *Encoder) encodeUint8Cond(n uint8) error { + if e.flags&useCompactIntsFlag != 0 { + return e.EncodeUint(uint64(n)) + } + return e.EncodeUint8(n) +} + +// EncodeUint16 encodes an uint16 in 3 bytes preserving type of the number. +func (e *Encoder) EncodeUint16(n uint16) error { + return e.write2(msgpcode.Uint16, n) +} + +func (e *Encoder) encodeUint16Cond(n uint16) error { + if e.flags&useCompactIntsFlag != 0 { + return e.EncodeUint(uint64(n)) + } + return e.EncodeUint16(n) +} + +// EncodeUint32 encodes an uint16 in 5 bytes preserving type of the number. +func (e *Encoder) EncodeUint32(n uint32) error { + return e.write4(msgpcode.Uint32, n) +} + +func (e *Encoder) encodeUint32Cond(n uint32) error { + if e.flags&useCompactIntsFlag != 0 { + return e.EncodeUint(uint64(n)) + } + return e.EncodeUint32(n) +} + +// EncodeUint64 encodes an uint16 in 9 bytes preserving type of the number. +func (e *Encoder) EncodeUint64(n uint64) error { + return e.write8(msgpcode.Uint64, n) +} + +func (e *Encoder) encodeUint64Cond(n uint64) error { + if e.flags&useCompactIntsFlag != 0 { + return e.EncodeUint(n) + } + return e.EncodeUint64(n) +} + +// EncodeInt8 encodes an int8 in 2 bytes preserving type of the number. +func (e *Encoder) EncodeInt8(n int8) error { + return e.write1(msgpcode.Int8, uint8(n)) +} + +func (e *Encoder) encodeInt8Cond(n int8) error { + if e.flags&useCompactIntsFlag != 0 { + return e.EncodeInt(int64(n)) + } + return e.EncodeInt8(n) +} + +// EncodeInt16 encodes an int16 in 3 bytes preserving type of the number. +func (e *Encoder) EncodeInt16(n int16) error { + return e.write2(msgpcode.Int16, uint16(n)) +} + +func (e *Encoder) encodeInt16Cond(n int16) error { + if e.flags&useCompactIntsFlag != 0 { + return e.EncodeInt(int64(n)) + } + return e.EncodeInt16(n) +} + +// EncodeInt32 encodes an int32 in 5 bytes preserving type of the number. +func (e *Encoder) EncodeInt32(n int32) error { + return e.write4(msgpcode.Int32, uint32(n)) +} + +func (e *Encoder) encodeInt32Cond(n int32) error { + if e.flags&useCompactIntsFlag != 0 { + return e.EncodeInt(int64(n)) + } + return e.EncodeInt32(n) +} + +// EncodeInt64 encodes an int64 in 9 bytes preserving type of the number. +func (e *Encoder) EncodeInt64(n int64) error { + return e.write8(msgpcode.Int64, uint64(n)) +} + +func (e *Encoder) encodeInt64Cond(n int64) error { + if e.flags&useCompactIntsFlag != 0 { + return e.EncodeInt(n) + } + return e.EncodeInt64(n) +} + +// EncodeUnsignedNumber encodes an uint64 in 1, 2, 3, 5, or 9 bytes. +// Type of the number is lost during encoding. +func (e *Encoder) EncodeUint(n uint64) error { + if n <= math.MaxInt8 { + return e.w.WriteByte(byte(n)) + } + if n <= math.MaxUint8 { + return e.EncodeUint8(uint8(n)) + } + if n <= math.MaxUint16 { + return e.EncodeUint16(uint16(n)) + } + if n <= math.MaxUint32 { + return e.EncodeUint32(uint32(n)) + } + return e.EncodeUint64(n) +} + +// EncodeNumber encodes an int64 in 1, 2, 3, 5, or 9 bytes. +// Type of the number is lost during encoding. +func (e *Encoder) EncodeInt(n int64) error { + if n >= 0 { + return e.EncodeUint(uint64(n)) + } + if n >= int64(int8(msgpcode.NegFixedNumLow)) { + return e.w.WriteByte(byte(n)) + } + if n >= math.MinInt8 { + return e.EncodeInt8(int8(n)) + } + if n >= math.MinInt16 { + return e.EncodeInt16(int16(n)) + } + if n >= math.MinInt32 { + return e.EncodeInt32(int32(n)) + } + return e.EncodeInt64(n) +} + +func (e *Encoder) EncodeFloat32(n float32) error { + if e.flags&useCompactFloatsFlag != 0 { + if float32(int64(n)) == n { + return e.EncodeInt(int64(n)) + } + } + return e.write4(msgpcode.Float, math.Float32bits(n)) +} + +func (e *Encoder) EncodeFloat64(n float64) error { + if e.flags&useCompactFloatsFlag != 0 { + // Both NaN and Inf convert to int64(-0x8000000000000000) + // If n is NaN then it never compares true with any other value + // If n is Inf then it doesn't convert from int64 back to +/-Inf + // In both cases the comparison works. + if float64(int64(n)) == n { + return e.EncodeInt(int64(n)) + } + } + return e.write8(msgpcode.Double, math.Float64bits(n)) +} + +func (e *Encoder) write1(code byte, n uint8) error { + e.buf = e.buf[:2] + e.buf[0] = code + e.buf[1] = n + return e.write(e.buf) +} + +func (e *Encoder) write2(code byte, n uint16) error { + e.buf = e.buf[:3] + e.buf[0] = code + e.buf[1] = byte(n >> 8) + e.buf[2] = byte(n) + return e.write(e.buf) +} + +func (e *Encoder) write4(code byte, n uint32) error { + e.buf = e.buf[:5] + e.buf[0] = code + e.buf[1] = byte(n >> 24) + e.buf[2] = byte(n >> 16) + e.buf[3] = byte(n >> 8) + e.buf[4] = byte(n) + return e.write(e.buf) +} + +func (e *Encoder) write8(code byte, n uint64) error { + e.buf = e.buf[:9] + e.buf[0] = code + e.buf[1] = byte(n >> 56) + e.buf[2] = byte(n >> 48) + e.buf[3] = byte(n >> 40) + e.buf[4] = byte(n >> 32) + e.buf[5] = byte(n >> 24) + e.buf[6] = byte(n >> 16) + e.buf[7] = byte(n >> 8) + e.buf[8] = byte(n) + return e.write(e.buf) +} + +func encodeUintValue(e *Encoder, v reflect.Value) error { + return e.EncodeUint(v.Uint()) +} + +func encodeIntValue(e *Encoder, v reflect.Value) error { + return e.EncodeInt(v.Int()) +} + +func encodeUint8CondValue(e *Encoder, v reflect.Value) error { + return e.encodeUint8Cond(uint8(v.Uint())) +} + +func encodeUint16CondValue(e *Encoder, v reflect.Value) error { + return e.encodeUint16Cond(uint16(v.Uint())) +} + +func encodeUint32CondValue(e *Encoder, v reflect.Value) error { + return e.encodeUint32Cond(uint32(v.Uint())) +} + +func encodeUint64CondValue(e *Encoder, v reflect.Value) error { + return e.encodeUint64Cond(v.Uint()) +} + +func encodeInt8CondValue(e *Encoder, v reflect.Value) error { + return e.encodeInt8Cond(int8(v.Int())) +} + +func encodeInt16CondValue(e *Encoder, v reflect.Value) error { + return e.encodeInt16Cond(int16(v.Int())) +} + +func encodeInt32CondValue(e *Encoder, v reflect.Value) error { + return e.encodeInt32Cond(int32(v.Int())) +} + +func encodeInt64CondValue(e *Encoder, v reflect.Value) error { + return e.encodeInt64Cond(v.Int()) +} + +func encodeFloat32Value(e *Encoder, v reflect.Value) error { + return e.EncodeFloat32(float32(v.Float())) +} + +func encodeFloat64Value(e *Encoder, v reflect.Value) error { + return e.EncodeFloat64(v.Float()) +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/encode_slice.go b/vendor/github.com/vmihailenco/msgpack/v5/encode_slice.go new file mode 100644 index 0000000000..ca46eadae5 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/encode_slice.go @@ -0,0 +1,139 @@ +package msgpack + +import ( + "math" + "reflect" + + "github.com/vmihailenco/msgpack/v5/msgpcode" +) + +var stringSliceType = reflect.TypeOf(([]string)(nil)) + +func encodeStringValue(e *Encoder, v reflect.Value) error { + return e.EncodeString(v.String()) +} + +func encodeByteSliceValue(e *Encoder, v reflect.Value) error { + return e.EncodeBytes(v.Bytes()) +} + +func encodeByteArrayValue(e *Encoder, v reflect.Value) error { + if err := e.EncodeBytesLen(v.Len()); err != nil { + return err + } + + if v.CanAddr() { + b := v.Slice(0, v.Len()).Bytes() + return e.write(b) + } + + e.buf = grow(e.buf, v.Len()) + reflect.Copy(reflect.ValueOf(e.buf), v) + return e.write(e.buf) +} + +func grow(b []byte, n int) []byte { + if cap(b) >= n { + return b[:n] + } + b = b[:cap(b)] + b = append(b, make([]byte, n-len(b))...) + return b +} + +func (e *Encoder) EncodeBytesLen(l int) error { + if l < 256 { + return e.write1(msgpcode.Bin8, uint8(l)) + } + if l <= math.MaxUint16 { + return e.write2(msgpcode.Bin16, uint16(l)) + } + return e.write4(msgpcode.Bin32, uint32(l)) +} + +func (e *Encoder) encodeStringLen(l int) error { + if l < 32 { + return e.writeCode(msgpcode.FixedStrLow | byte(l)) + } + if l < 256 { + return e.write1(msgpcode.Str8, uint8(l)) + } + if l <= math.MaxUint16 { + return e.write2(msgpcode.Str16, uint16(l)) + } + return e.write4(msgpcode.Str32, uint32(l)) +} + +func (e *Encoder) EncodeString(v string) error { + if intern := e.flags&useInternedStringsFlag != 0; intern || len(e.dict) > 0 { + return e.encodeInternedString(v, intern) + } + return e.encodeNormalString(v) +} + +func (e *Encoder) encodeNormalString(v string) error { + if err := e.encodeStringLen(len(v)); err != nil { + return err + } + return e.writeString(v) +} + +func (e *Encoder) EncodeBytes(v []byte) error { + if v == nil { + return e.EncodeNil() + } + if err := e.EncodeBytesLen(len(v)); err != nil { + return err + } + return e.write(v) +} + +func (e *Encoder) EncodeArrayLen(l int) error { + if l < 16 { + return e.writeCode(msgpcode.FixedArrayLow | byte(l)) + } + if l <= math.MaxUint16 { + return e.write2(msgpcode.Array16, uint16(l)) + } + return e.write4(msgpcode.Array32, uint32(l)) +} + +func encodeStringSliceValue(e *Encoder, v reflect.Value) error { + ss := v.Convert(stringSliceType).Interface().([]string) + return e.encodeStringSlice(ss) +} + +func (e *Encoder) encodeStringSlice(s []string) error { + if s == nil { + return e.EncodeNil() + } + if err := e.EncodeArrayLen(len(s)); err != nil { + return err + } + for _, v := range s { + if err := e.EncodeString(v); err != nil { + return err + } + } + return nil +} + +func encodeSliceValue(e *Encoder, v reflect.Value) error { + if v.IsNil() { + return e.EncodeNil() + } + return encodeArrayValue(e, v) +} + +func encodeArrayValue(e *Encoder, v reflect.Value) error { + l := v.Len() + if err := e.EncodeArrayLen(l); err != nil { + return err + } + for i := 0; i < l; i++ { + if err := e.EncodeValue(v.Index(i)); err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/encode_value.go b/vendor/github.com/vmihailenco/msgpack/v5/encode_value.go new file mode 100644 index 0000000000..48cf489fa1 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/encode_value.go @@ -0,0 +1,245 @@ +package msgpack + +import ( + "encoding" + "fmt" + "reflect" +) + +var valueEncoders []encoderFunc + +//nolint:gochecknoinits +func init() { + valueEncoders = []encoderFunc{ + reflect.Bool: encodeBoolValue, + reflect.Int: encodeIntValue, + reflect.Int8: encodeInt8CondValue, + reflect.Int16: encodeInt16CondValue, + reflect.Int32: encodeInt32CondValue, + reflect.Int64: encodeInt64CondValue, + reflect.Uint: encodeUintValue, + reflect.Uint8: encodeUint8CondValue, + reflect.Uint16: encodeUint16CondValue, + reflect.Uint32: encodeUint32CondValue, + reflect.Uint64: encodeUint64CondValue, + reflect.Float32: encodeFloat32Value, + reflect.Float64: encodeFloat64Value, + reflect.Complex64: encodeUnsupportedValue, + reflect.Complex128: encodeUnsupportedValue, + reflect.Array: encodeArrayValue, + reflect.Chan: encodeUnsupportedValue, + reflect.Func: encodeUnsupportedValue, + reflect.Interface: encodeInterfaceValue, + reflect.Map: encodeMapValue, + reflect.Ptr: encodeUnsupportedValue, + reflect.Slice: encodeSliceValue, + reflect.String: encodeStringValue, + reflect.Struct: encodeStructValue, + reflect.UnsafePointer: encodeUnsupportedValue, + } +} + +func getEncoder(typ reflect.Type) encoderFunc { + if v, ok := typeEncMap.Load(typ); ok { + return v.(encoderFunc) + } + fn := _getEncoder(typ) + typeEncMap.Store(typ, fn) + return fn +} + +func _getEncoder(typ reflect.Type) encoderFunc { + kind := typ.Kind() + + if kind == reflect.Ptr { + if _, ok := typeEncMap.Load(typ.Elem()); ok { + return ptrEncoderFunc(typ) + } + } + + if typ.Implements(customEncoderType) { + return encodeCustomValue + } + if typ.Implements(marshalerType) { + return marshalValue + } + if typ.Implements(binaryMarshalerType) { + return marshalBinaryValue + } + if typ.Implements(textMarshalerType) { + return marshalTextValue + } + + // Addressable struct field value. + if kind != reflect.Ptr { + ptr := reflect.PtrTo(typ) + if ptr.Implements(customEncoderType) { + return encodeCustomValuePtr + } + if ptr.Implements(marshalerType) { + return marshalValuePtr + } + if ptr.Implements(binaryMarshalerType) { + return marshalBinaryValueAddr + } + if ptr.Implements(textMarshalerType) { + return marshalTextValueAddr + } + } + + if typ == errorType { + return encodeErrorValue + } + + switch kind { + case reflect.Ptr: + return ptrEncoderFunc(typ) + case reflect.Slice: + elem := typ.Elem() + if elem.Kind() == reflect.Uint8 { + return encodeByteSliceValue + } + if elem == stringType { + return encodeStringSliceValue + } + case reflect.Array: + if typ.Elem().Kind() == reflect.Uint8 { + return encodeByteArrayValue + } + case reflect.Map: + if typ.Key() == stringType { + switch typ.Elem() { + case stringType: + return encodeMapStringStringValue + case interfaceType: + return encodeMapStringInterfaceValue + } + } + } + + return valueEncoders[kind] +} + +func ptrEncoderFunc(typ reflect.Type) encoderFunc { + encoder := getEncoder(typ.Elem()) + return func(e *Encoder, v reflect.Value) error { + if v.IsNil() { + return e.EncodeNil() + } + return encoder(e, v.Elem()) + } +} + +func encodeCustomValuePtr(e *Encoder, v reflect.Value) error { + if !v.CanAddr() { + return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface()) + } + encoder := v.Addr().Interface().(CustomEncoder) + return encoder.EncodeMsgpack(e) +} + +func encodeCustomValue(e *Encoder, v reflect.Value) error { + if nilable(v.Kind()) && v.IsNil() { + return e.EncodeNil() + } + + encoder := v.Interface().(CustomEncoder) + return encoder.EncodeMsgpack(e) +} + +func marshalValuePtr(e *Encoder, v reflect.Value) error { + if !v.CanAddr() { + return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface()) + } + return marshalValue(e, v.Addr()) +} + +func marshalValue(e *Encoder, v reflect.Value) error { + if nilable(v.Kind()) && v.IsNil() { + return e.EncodeNil() + } + + marshaler := v.Interface().(Marshaler) + b, err := marshaler.MarshalMsgpack() + if err != nil { + return err + } + _, err = e.w.Write(b) + return err +} + +func encodeBoolValue(e *Encoder, v reflect.Value) error { + return e.EncodeBool(v.Bool()) +} + +func encodeInterfaceValue(e *Encoder, v reflect.Value) error { + if v.IsNil() { + return e.EncodeNil() + } + return e.EncodeValue(v.Elem()) +} + +func encodeErrorValue(e *Encoder, v reflect.Value) error { + if v.IsNil() { + return e.EncodeNil() + } + return e.EncodeString(v.Interface().(error).Error()) +} + +func encodeUnsupportedValue(e *Encoder, v reflect.Value) error { + return fmt.Errorf("msgpack: Encode(unsupported %s)", v.Type()) +} + +func nilable(kind reflect.Kind) bool { + switch kind { + case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: + return true + } + return false +} + +//------------------------------------------------------------------------------ + +func marshalBinaryValueAddr(e *Encoder, v reflect.Value) error { + if !v.CanAddr() { + return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface()) + } + return marshalBinaryValue(e, v.Addr()) +} + +func marshalBinaryValue(e *Encoder, v reflect.Value) error { + if nilable(v.Kind()) && v.IsNil() { + return e.EncodeNil() + } + + marshaler := v.Interface().(encoding.BinaryMarshaler) + data, err := marshaler.MarshalBinary() + if err != nil { + return err + } + + return e.EncodeBytes(data) +} + +//------------------------------------------------------------------------------ + +func marshalTextValueAddr(e *Encoder, v reflect.Value) error { + if !v.CanAddr() { + return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface()) + } + return marshalTextValue(e, v.Addr()) +} + +func marshalTextValue(e *Encoder, v reflect.Value) error { + if nilable(v.Kind()) && v.IsNil() { + return e.EncodeNil() + } + + marshaler := v.Interface().(encoding.TextMarshaler) + data, err := marshaler.MarshalText() + if err != nil { + return err + } + + return e.EncodeBytes(data) +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/ext.go b/vendor/github.com/vmihailenco/msgpack/v5/ext.go new file mode 100644 index 0000000000..76e11603d9 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/ext.go @@ -0,0 +1,303 @@ +package msgpack + +import ( + "fmt" + "math" + "reflect" + + "github.com/vmihailenco/msgpack/v5/msgpcode" +) + +type extInfo struct { + Type reflect.Type + Decoder func(d *Decoder, v reflect.Value, extLen int) error +} + +var extTypes = make(map[int8]*extInfo) + +type MarshalerUnmarshaler interface { + Marshaler + Unmarshaler +} + +func RegisterExt(extID int8, value MarshalerUnmarshaler) { + RegisterExtEncoder(extID, value, func(e *Encoder, v reflect.Value) ([]byte, error) { + marshaler := v.Interface().(Marshaler) + return marshaler.MarshalMsgpack() + }) + RegisterExtDecoder(extID, value, func(d *Decoder, v reflect.Value, extLen int) error { + b, err := d.readN(extLen) + if err != nil { + return err + } + return v.Interface().(Unmarshaler).UnmarshalMsgpack(b) + }) +} + +func UnregisterExt(extID int8) { + unregisterExtEncoder(extID) + unregisterExtDecoder(extID) +} + +func RegisterExtEncoder( + extID int8, + value interface{}, + encoder func(enc *Encoder, v reflect.Value) ([]byte, error), +) { + unregisterExtEncoder(extID) + + typ := reflect.TypeOf(value) + extEncoder := makeExtEncoder(extID, typ, encoder) + typeEncMap.Store(extID, typ) + typeEncMap.Store(typ, extEncoder) + if typ.Kind() == reflect.Ptr { + typeEncMap.Store(typ.Elem(), makeExtEncoderAddr(extEncoder)) + } +} + +func unregisterExtEncoder(extID int8) { + t, ok := typeEncMap.Load(extID) + if !ok { + return + } + typeEncMap.Delete(extID) + typ := t.(reflect.Type) + typeEncMap.Delete(typ) + if typ.Kind() == reflect.Ptr { + typeEncMap.Delete(typ.Elem()) + } +} + +func makeExtEncoder( + extID int8, + typ reflect.Type, + encoder func(enc *Encoder, v reflect.Value) ([]byte, error), +) encoderFunc { + nilable := typ.Kind() == reflect.Ptr + + return func(e *Encoder, v reflect.Value) error { + if nilable && v.IsNil() { + return e.EncodeNil() + } + + b, err := encoder(e, v) + if err != nil { + return err + } + + if err := e.EncodeExtHeader(extID, len(b)); err != nil { + return err + } + + return e.write(b) + } +} + +func makeExtEncoderAddr(extEncoder encoderFunc) encoderFunc { + return func(e *Encoder, v reflect.Value) error { + if !v.CanAddr() { + return fmt.Errorf("msgpack: Decode(nonaddressable %T)", v.Interface()) + } + return extEncoder(e, v.Addr()) + } +} + +func RegisterExtDecoder( + extID int8, + value interface{}, + decoder func(dec *Decoder, v reflect.Value, extLen int) error, +) { + unregisterExtDecoder(extID) + + typ := reflect.TypeOf(value) + extDecoder := makeExtDecoder(extID, typ, decoder) + extTypes[extID] = &extInfo{ + Type: typ, + Decoder: decoder, + } + + typeDecMap.Store(extID, typ) + typeDecMap.Store(typ, extDecoder) + if typ.Kind() == reflect.Ptr { + typeDecMap.Store(typ.Elem(), makeExtDecoderAddr(extDecoder)) + } +} + +func unregisterExtDecoder(extID int8) { + t, ok := typeDecMap.Load(extID) + if !ok { + return + } + typeDecMap.Delete(extID) + delete(extTypes, extID) + typ := t.(reflect.Type) + typeDecMap.Delete(typ) + if typ.Kind() == reflect.Ptr { + typeDecMap.Delete(typ.Elem()) + } +} + +func makeExtDecoder( + wantedExtID int8, + typ reflect.Type, + decoder func(d *Decoder, v reflect.Value, extLen int) error, +) decoderFunc { + return nilAwareDecoder(typ, func(d *Decoder, v reflect.Value) error { + extID, extLen, err := d.DecodeExtHeader() + if err != nil { + return err + } + if extID != wantedExtID { + return fmt.Errorf("msgpack: got ext type=%d, wanted %d", extID, wantedExtID) + } + return decoder(d, v, extLen) + }) +} + +func makeExtDecoderAddr(extDecoder decoderFunc) decoderFunc { + return func(d *Decoder, v reflect.Value) error { + if !v.CanAddr() { + return fmt.Errorf("msgpack: Decode(nonaddressable %T)", v.Interface()) + } + return extDecoder(d, v.Addr()) + } +} + +func (e *Encoder) EncodeExtHeader(extID int8, extLen int) error { + if err := e.encodeExtLen(extLen); err != nil { + return err + } + if err := e.w.WriteByte(byte(extID)); err != nil { + return err + } + return nil +} + +func (e *Encoder) encodeExtLen(l int) error { + switch l { + case 1: + return e.writeCode(msgpcode.FixExt1) + case 2: + return e.writeCode(msgpcode.FixExt2) + case 4: + return e.writeCode(msgpcode.FixExt4) + case 8: + return e.writeCode(msgpcode.FixExt8) + case 16: + return e.writeCode(msgpcode.FixExt16) + } + if l <= math.MaxUint8 { + return e.write1(msgpcode.Ext8, uint8(l)) + } + if l <= math.MaxUint16 { + return e.write2(msgpcode.Ext16, uint16(l)) + } + return e.write4(msgpcode.Ext32, uint32(l)) +} + +func (d *Decoder) DecodeExtHeader() (extID int8, extLen int, err error) { + c, err := d.readCode() + if err != nil { + return + } + return d.extHeader(c) +} + +func (d *Decoder) extHeader(c byte) (int8, int, error) { + extLen, err := d.parseExtLen(c) + if err != nil { + return 0, 0, err + } + + extID, err := d.readCode() + if err != nil { + return 0, 0, err + } + + return int8(extID), extLen, nil +} + +func (d *Decoder) parseExtLen(c byte) (int, error) { + switch c { + case msgpcode.FixExt1: + return 1, nil + case msgpcode.FixExt2: + return 2, nil + case msgpcode.FixExt4: + return 4, nil + case msgpcode.FixExt8: + return 8, nil + case msgpcode.FixExt16: + return 16, nil + case msgpcode.Ext8: + n, err := d.uint8() + return int(n), err + case msgpcode.Ext16: + n, err := d.uint16() + return int(n), err + case msgpcode.Ext32: + n, err := d.uint32() + return int(n), err + default: + return 0, fmt.Errorf("msgpack: invalid code=%x decoding ext len", c) + } +} + +func (d *Decoder) decodeInterfaceExt(c byte) (interface{}, error) { + extID, extLen, err := d.extHeader(c) + if err != nil { + return nil, err + } + + info, ok := extTypes[extID] + if !ok { + return nil, fmt.Errorf("msgpack: unknown ext id=%d", extID) + } + + v := reflect.New(info.Type).Elem() + if nilable(v.Kind()) && v.IsNil() { + v.Set(reflect.New(info.Type.Elem())) + } + + if err := info.Decoder(d, v, extLen); err != nil { + return nil, err + } + + return v.Interface(), nil +} + +func (d *Decoder) skipExt(c byte) error { + n, err := d.parseExtLen(c) + if err != nil { + return err + } + return d.skipN(n + 1) +} + +func (d *Decoder) skipExtHeader(c byte) error { + // Read ext type. + _, err := d.readCode() + if err != nil { + return err + } + // Read ext body len. + for i := 0; i < extHeaderLen(c); i++ { + _, err := d.readCode() + if err != nil { + return err + } + } + return nil +} + +func extHeaderLen(c byte) int { + switch c { + case msgpcode.Ext8: + return 1 + case msgpcode.Ext16: + return 2 + case msgpcode.Ext32: + return 4 + } + return 0 +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/intern.go b/vendor/github.com/vmihailenco/msgpack/v5/intern.go new file mode 100644 index 0000000000..be0316a83d --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/intern.go @@ -0,0 +1,238 @@ +package msgpack + +import ( + "fmt" + "math" + "reflect" + + "github.com/vmihailenco/msgpack/v5/msgpcode" +) + +const ( + minInternedStringLen = 3 + maxDictLen = math.MaxUint16 +) + +var internedStringExtID = int8(math.MinInt8) + +func init() { + extTypes[internedStringExtID] = &extInfo{ + Type: stringType, + Decoder: decodeInternedStringExt, + } +} + +func decodeInternedStringExt(d *Decoder, v reflect.Value, extLen int) error { + idx, err := d.decodeInternedStringIndex(extLen) + if err != nil { + return err + } + + s, err := d.internedStringAtIndex(idx) + if err != nil { + return err + } + + v.SetString(s) + return nil +} + +//------------------------------------------------------------------------------ + +func encodeInternedInterfaceValue(e *Encoder, v reflect.Value) error { + if v.IsNil() { + return e.EncodeNil() + } + + v = v.Elem() + if v.Kind() == reflect.String { + return e.encodeInternedString(v.String(), true) + } + return e.EncodeValue(v) +} + +func encodeInternedStringValue(e *Encoder, v reflect.Value) error { + return e.encodeInternedString(v.String(), true) +} + +func (e *Encoder) encodeInternedString(s string, intern bool) error { + // Interned string takes at least 3 bytes. Plain string 1 byte + string len. + if len(s) >= minInternedStringLen { + if idx, ok := e.dict[s]; ok { + return e.encodeInternedStringIndex(idx) + } + + if intern && len(e.dict) < maxDictLen { + if e.dict == nil { + e.dict = make(map[string]int) + } + idx := len(e.dict) + e.dict[s] = idx + } + } + + return e.encodeNormalString(s) +} + +func (e *Encoder) encodeInternedStringIndex(idx int) error { + if idx <= math.MaxUint8 { + if err := e.writeCode(msgpcode.FixExt1); err != nil { + return err + } + return e.write1(byte(internedStringExtID), uint8(idx)) + } + + if idx <= math.MaxUint16 { + if err := e.writeCode(msgpcode.FixExt2); err != nil { + return err + } + return e.write2(byte(internedStringExtID), uint16(idx)) + } + + if uint64(idx) <= math.MaxUint32 { + if err := e.writeCode(msgpcode.FixExt4); err != nil { + return err + } + return e.write4(byte(internedStringExtID), uint32(idx)) + } + + return fmt.Errorf("msgpack: interned string index=%d is too large", idx) +} + +//------------------------------------------------------------------------------ + +func decodeInternedInterfaceValue(d *Decoder, v reflect.Value) error { + s, err := d.decodeInternedString(true) + if err == nil { + v.Set(reflect.ValueOf(s)) + return nil + } + if err != nil { + if _, ok := err.(unexpectedCodeError); !ok { + return err + } + } + + if err := d.s.UnreadByte(); err != nil { + return err + } + return decodeInterfaceValue(d, v) +} + +func decodeInternedStringValue(d *Decoder, v reflect.Value) error { + s, err := d.decodeInternedString(true) + if err != nil { + return err + } + + v.SetString(s) + return nil +} + +func (d *Decoder) decodeInternedString(intern bool) (string, error) { + c, err := d.readCode() + if err != nil { + return "", err + } + + if msgpcode.IsFixedString(c) { + n := int(c & msgpcode.FixedStrMask) + return d.decodeInternedStringWithLen(n, intern) + } + + switch c { + case msgpcode.Nil: + return "", nil + case msgpcode.FixExt1, msgpcode.FixExt2, msgpcode.FixExt4: + typeID, extLen, err := d.extHeader(c) + if err != nil { + return "", err + } + if typeID != internedStringExtID { + err := fmt.Errorf("msgpack: got ext type=%d, wanted %d", + typeID, internedStringExtID) + return "", err + } + + idx, err := d.decodeInternedStringIndex(extLen) + if err != nil { + return "", err + } + + return d.internedStringAtIndex(idx) + case msgpcode.Str8, msgpcode.Bin8: + n, err := d.uint8() + if err != nil { + return "", err + } + return d.decodeInternedStringWithLen(int(n), intern) + case msgpcode.Str16, msgpcode.Bin16: + n, err := d.uint16() + if err != nil { + return "", err + } + return d.decodeInternedStringWithLen(int(n), intern) + case msgpcode.Str32, msgpcode.Bin32: + n, err := d.uint32() + if err != nil { + return "", err + } + return d.decodeInternedStringWithLen(int(n), intern) + } + + return "", unexpectedCodeError{ + code: c, + hint: "interned string", + } +} + +func (d *Decoder) decodeInternedStringIndex(extLen int) (int, error) { + switch extLen { + case 1: + n, err := d.uint8() + if err != nil { + return 0, err + } + return int(n), nil + case 2: + n, err := d.uint16() + if err != nil { + return 0, err + } + return int(n), nil + case 4: + n, err := d.uint32() + if err != nil { + return 0, err + } + return int(n), nil + } + + err := fmt.Errorf("msgpack: unsupported ext len=%d decoding interned string", extLen) + return 0, err +} + +func (d *Decoder) internedStringAtIndex(idx int) (string, error) { + if idx >= len(d.dict) { + err := fmt.Errorf("msgpack: interned string at index=%d does not exist", idx) + return "", err + } + return d.dict[idx], nil +} + +func (d *Decoder) decodeInternedStringWithLen(n int, intern bool) (string, error) { + if n <= 0 { + return "", nil + } + + s, err := d.stringWithLen(n) + if err != nil { + return "", err + } + + if intern && len(s) >= minInternedStringLen && len(d.dict) < maxDictLen { + d.dict = append(d.dict, s) + } + + return s, nil +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/msgpack.go b/vendor/github.com/vmihailenco/msgpack/v5/msgpack.go new file mode 100644 index 0000000000..4db2fa2c71 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/msgpack.go @@ -0,0 +1,52 @@ +package msgpack + +import "fmt" + +type Marshaler interface { + MarshalMsgpack() ([]byte, error) +} + +type Unmarshaler interface { + UnmarshalMsgpack([]byte) error +} + +type CustomEncoder interface { + EncodeMsgpack(*Encoder) error +} + +type CustomDecoder interface { + DecodeMsgpack(*Decoder) error +} + +//------------------------------------------------------------------------------ + +type RawMessage []byte + +var ( + _ CustomEncoder = (RawMessage)(nil) + _ CustomDecoder = (*RawMessage)(nil) +) + +func (m RawMessage) EncodeMsgpack(enc *Encoder) error { + return enc.write(m) +} + +func (m *RawMessage) DecodeMsgpack(dec *Decoder) error { + msg, err := dec.DecodeRaw() + if err != nil { + return err + } + *m = msg + return nil +} + +//------------------------------------------------------------------------------ + +type unexpectedCodeError struct { + code byte + hint string +} + +func (err unexpectedCodeError) Error() string { + return fmt.Sprintf("msgpack: unexpected code=%x decoding %s", err.code, err.hint) +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/msgpcode/msgpcode.go b/vendor/github.com/vmihailenco/msgpack/v5/msgpcode/msgpcode.go new file mode 100644 index 0000000000..e35389cccf --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/msgpcode/msgpcode.go @@ -0,0 +1,88 @@ +package msgpcode + +var ( + PosFixedNumHigh byte = 0x7f + NegFixedNumLow byte = 0xe0 + + Nil byte = 0xc0 + + False byte = 0xc2 + True byte = 0xc3 + + Float byte = 0xca + Double byte = 0xcb + + Uint8 byte = 0xcc + Uint16 byte = 0xcd + Uint32 byte = 0xce + Uint64 byte = 0xcf + + Int8 byte = 0xd0 + Int16 byte = 0xd1 + Int32 byte = 0xd2 + Int64 byte = 0xd3 + + FixedStrLow byte = 0xa0 + FixedStrHigh byte = 0xbf + FixedStrMask byte = 0x1f + Str8 byte = 0xd9 + Str16 byte = 0xda + Str32 byte = 0xdb + + Bin8 byte = 0xc4 + Bin16 byte = 0xc5 + Bin32 byte = 0xc6 + + FixedArrayLow byte = 0x90 + FixedArrayHigh byte = 0x9f + FixedArrayMask byte = 0xf + Array16 byte = 0xdc + Array32 byte = 0xdd + + FixedMapLow byte = 0x80 + FixedMapHigh byte = 0x8f + FixedMapMask byte = 0xf + Map16 byte = 0xde + Map32 byte = 0xdf + + FixExt1 byte = 0xd4 + FixExt2 byte = 0xd5 + FixExt4 byte = 0xd6 + FixExt8 byte = 0xd7 + FixExt16 byte = 0xd8 + Ext8 byte = 0xc7 + Ext16 byte = 0xc8 + Ext32 byte = 0xc9 +) + +func IsFixedNum(c byte) bool { + return c <= PosFixedNumHigh || c >= NegFixedNumLow +} + +func IsFixedMap(c byte) bool { + return c >= FixedMapLow && c <= FixedMapHigh +} + +func IsFixedArray(c byte) bool { + return c >= FixedArrayLow && c <= FixedArrayHigh +} + +func IsFixedString(c byte) bool { + return c >= FixedStrLow && c <= FixedStrHigh +} + +func IsString(c byte) bool { + return IsFixedString(c) || c == Str8 || c == Str16 || c == Str32 +} + +func IsBin(c byte) bool { + return c == Bin8 || c == Bin16 || c == Bin32 +} + +func IsFixedExt(c byte) bool { + return c >= FixExt1 && c <= FixExt16 +} + +func IsExt(c byte) bool { + return IsFixedExt(c) || c == Ext8 || c == Ext16 || c == Ext32 +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/package.json b/vendor/github.com/vmihailenco/msgpack/v5/package.json new file mode 100644 index 0000000000..298910d45c --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/package.json @@ -0,0 +1,4 @@ +{ + "name": "msgpack", + "version": "5.3.5" +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/safe.go b/vendor/github.com/vmihailenco/msgpack/v5/safe.go new file mode 100644 index 0000000000..8352c9dcef --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/safe.go @@ -0,0 +1,13 @@ +// +build appengine + +package msgpack + +// bytesToString converts byte slice to string. +func bytesToString(b []byte) string { + return string(b) +} + +// stringToBytes converts string to byte slice. +func stringToBytes(s string) []byte { + return []byte(s) +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/time.go b/vendor/github.com/vmihailenco/msgpack/v5/time.go new file mode 100644 index 0000000000..44566ec076 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/time.go @@ -0,0 +1,145 @@ +package msgpack + +import ( + "encoding/binary" + "fmt" + "reflect" + "time" + + "github.com/vmihailenco/msgpack/v5/msgpcode" +) + +var timeExtID int8 = -1 + +func init() { + RegisterExtEncoder(timeExtID, time.Time{}, timeEncoder) + RegisterExtDecoder(timeExtID, time.Time{}, timeDecoder) +} + +func timeEncoder(e *Encoder, v reflect.Value) ([]byte, error) { + return e.encodeTime(v.Interface().(time.Time)), nil +} + +func timeDecoder(d *Decoder, v reflect.Value, extLen int) error { + tm, err := d.decodeTime(extLen) + if err != nil { + return err + } + + ptr := v.Addr().Interface().(*time.Time) + *ptr = tm + + return nil +} + +func (e *Encoder) EncodeTime(tm time.Time) error { + b := e.encodeTime(tm) + if err := e.encodeExtLen(len(b)); err != nil { + return err + } + if err := e.w.WriteByte(byte(timeExtID)); err != nil { + return err + } + return e.write(b) +} + +func (e *Encoder) encodeTime(tm time.Time) []byte { + if e.timeBuf == nil { + e.timeBuf = make([]byte, 12) + } + + secs := uint64(tm.Unix()) + if secs>>34 == 0 { + data := uint64(tm.Nanosecond())<<34 | secs + + if data&0xffffffff00000000 == 0 { + b := e.timeBuf[:4] + binary.BigEndian.PutUint32(b, uint32(data)) + return b + } + + b := e.timeBuf[:8] + binary.BigEndian.PutUint64(b, data) + return b + } + + b := e.timeBuf[:12] + binary.BigEndian.PutUint32(b, uint32(tm.Nanosecond())) + binary.BigEndian.PutUint64(b[4:], secs) + return b +} + +func (d *Decoder) DecodeTime() (time.Time, error) { + c, err := d.readCode() + if err != nil { + return time.Time{}, err + } + + // Legacy format. + if c == msgpcode.FixedArrayLow|2 { + sec, err := d.DecodeInt64() + if err != nil { + return time.Time{}, err + } + + nsec, err := d.DecodeInt64() + if err != nil { + return time.Time{}, err + } + + return time.Unix(sec, nsec), nil + } + + if msgpcode.IsString(c) { + s, err := d.string(c) + if err != nil { + return time.Time{}, err + } + return time.Parse(time.RFC3339Nano, s) + } + + extID, extLen, err := d.extHeader(c) + if err != nil { + return time.Time{}, err + } + + if extID != timeExtID { + return time.Time{}, fmt.Errorf("msgpack: invalid time ext id=%d", extID) + } + + tm, err := d.decodeTime(extLen) + if err != nil { + return tm, err + } + + if tm.IsZero() { + // Zero time does not have timezone information. + return tm.UTC(), nil + } + return tm, nil +} + +func (d *Decoder) decodeTime(extLen int) (time.Time, error) { + b, err := d.readN(extLen) + if err != nil { + return time.Time{}, err + } + + switch len(b) { + case 4: + sec := binary.BigEndian.Uint32(b) + return time.Unix(int64(sec), 0), nil + case 8: + sec := binary.BigEndian.Uint64(b) + nsec := int64(sec >> 34) + sec &= 0x00000003ffffffff + return time.Unix(int64(sec), nsec), nil + case 12: + nsec := binary.BigEndian.Uint32(b) + sec := binary.BigEndian.Uint64(b[4:]) + return time.Unix(int64(sec), int64(nsec)), nil + default: + err = fmt.Errorf("msgpack: invalid ext len=%d decoding time", extLen) + return time.Time{}, err + } +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/types.go b/vendor/github.com/vmihailenco/msgpack/v5/types.go new file mode 100644 index 0000000000..69aca611b2 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/types.go @@ -0,0 +1,407 @@ +package msgpack + +import ( + "encoding" + "fmt" + "log" + "reflect" + "sync" + + "github.com/vmihailenco/tagparser/v2" +) + +var errorType = reflect.TypeOf((*error)(nil)).Elem() + +var ( + customEncoderType = reflect.TypeOf((*CustomEncoder)(nil)).Elem() + customDecoderType = reflect.TypeOf((*CustomDecoder)(nil)).Elem() +) + +var ( + marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() + unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() +) + +var ( + binaryMarshalerType = reflect.TypeOf((*encoding.BinaryMarshaler)(nil)).Elem() + binaryUnmarshalerType = reflect.TypeOf((*encoding.BinaryUnmarshaler)(nil)).Elem() +) + +var ( + textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() + textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() +) + +type ( + encoderFunc func(*Encoder, reflect.Value) error + decoderFunc func(*Decoder, reflect.Value) error +) + +var ( + typeEncMap sync.Map + typeDecMap sync.Map +) + +// Register registers encoder and decoder functions for a value. +// This is low level API and in most cases you should prefer implementing +// CustomEncoder/CustomDecoder or Marshaler/Unmarshaler interfaces. +func Register(value interface{}, enc encoderFunc, dec decoderFunc) { + typ := reflect.TypeOf(value) + if enc != nil { + typeEncMap.Store(typ, enc) + } + if dec != nil { + typeDecMap.Store(typ, dec) + } +} + +//------------------------------------------------------------------------------ + +const defaultStructTag = "msgpack" + +var structs = newStructCache() + +type structCache struct { + m sync.Map +} + +type structCacheKey struct { + tag string + typ reflect.Type +} + +func newStructCache() *structCache { + return new(structCache) +} + +func (m *structCache) Fields(typ reflect.Type, tag string) *fields { + key := structCacheKey{tag: tag, typ: typ} + + if v, ok := m.m.Load(key); ok { + return v.(*fields) + } + + fs := getFields(typ, tag) + m.m.Store(key, fs) + + return fs +} + +//------------------------------------------------------------------------------ + +type field struct { + name string + index []int + omitEmpty bool + encoder encoderFunc + decoder decoderFunc +} + +func (f *field) Omit(strct reflect.Value, forced bool) bool { + v, ok := fieldByIndex(strct, f.index) + if !ok { + return true + } + return (f.omitEmpty || forced) && isEmptyValue(v) +} + +func (f *field) EncodeValue(e *Encoder, strct reflect.Value) error { + v, ok := fieldByIndex(strct, f.index) + if !ok { + return e.EncodeNil() + } + return f.encoder(e, v) +} + +func (f *field) DecodeValue(d *Decoder, strct reflect.Value) error { + v := fieldByIndexAlloc(strct, f.index) + return f.decoder(d, v) +} + +//------------------------------------------------------------------------------ + +type fields struct { + Type reflect.Type + Map map[string]*field + List []*field + AsArray bool + + hasOmitEmpty bool +} + +func newFields(typ reflect.Type) *fields { + return &fields{ + Type: typ, + Map: make(map[string]*field, typ.NumField()), + List: make([]*field, 0, typ.NumField()), + } +} + +func (fs *fields) Add(field *field) { + fs.warnIfFieldExists(field.name) + fs.Map[field.name] = field + fs.List = append(fs.List, field) + if field.omitEmpty { + fs.hasOmitEmpty = true + } +} + +func (fs *fields) warnIfFieldExists(name string) { + if _, ok := fs.Map[name]; ok { + log.Printf("msgpack: %s already has field=%s", fs.Type, name) + } +} + +func (fs *fields) OmitEmpty(strct reflect.Value, forced bool) []*field { + if !fs.hasOmitEmpty && !forced { + return fs.List + } + + fields := make([]*field, 0, len(fs.List)) + + for _, f := range fs.List { + if !f.Omit(strct, forced) { + fields = append(fields, f) + } + } + + return fields +} + +func getFields(typ reflect.Type, fallbackTag string) *fields { + fs := newFields(typ) + + var omitEmpty bool + for i := 0; i < typ.NumField(); i++ { + f := typ.Field(i) + + tagStr := f.Tag.Get(defaultStructTag) + if tagStr == "" && fallbackTag != "" { + tagStr = f.Tag.Get(fallbackTag) + } + + tag := tagparser.Parse(tagStr) + if tag.Name == "-" { + continue + } + + if f.Name == "_msgpack" { + fs.AsArray = tag.HasOption("as_array") || tag.HasOption("asArray") + if tag.HasOption("omitempty") { + omitEmpty = true + } + } + + if f.PkgPath != "" && !f.Anonymous { + continue + } + + field := &field{ + name: tag.Name, + index: f.Index, + omitEmpty: omitEmpty || tag.HasOption("omitempty"), + } + + if tag.HasOption("intern") { + switch f.Type.Kind() { + case reflect.Interface: + field.encoder = encodeInternedInterfaceValue + field.decoder = decodeInternedInterfaceValue + case reflect.String: + field.encoder = encodeInternedStringValue + field.decoder = decodeInternedStringValue + default: + err := fmt.Errorf("msgpack: intern strings are not supported on %s", f.Type) + panic(err) + } + } else { + field.encoder = getEncoder(f.Type) + field.decoder = getDecoder(f.Type) + } + + if field.name == "" { + field.name = f.Name + } + + if f.Anonymous && !tag.HasOption("noinline") { + inline := tag.HasOption("inline") + if inline { + inlineFields(fs, f.Type, field, fallbackTag) + } else { + inline = shouldInline(fs, f.Type, field, fallbackTag) + } + + if inline { + if _, ok := fs.Map[field.name]; ok { + log.Printf("msgpack: %s already has field=%s", fs.Type, field.name) + } + fs.Map[field.name] = field + continue + } + } + + fs.Add(field) + + if alias, ok := tag.Options["alias"]; ok { + fs.warnIfFieldExists(alias) + fs.Map[alias] = field + } + } + return fs +} + +var ( + encodeStructValuePtr uintptr + decodeStructValuePtr uintptr +) + +//nolint:gochecknoinits +func init() { + encodeStructValuePtr = reflect.ValueOf(encodeStructValue).Pointer() + decodeStructValuePtr = reflect.ValueOf(decodeStructValue).Pointer() +} + +func inlineFields(fs *fields, typ reflect.Type, f *field, tag string) { + inlinedFields := getFields(typ, tag).List + for _, field := range inlinedFields { + if _, ok := fs.Map[field.name]; ok { + // Don't inline shadowed fields. + continue + } + field.index = append(f.index, field.index...) + fs.Add(field) + } +} + +func shouldInline(fs *fields, typ reflect.Type, f *field, tag string) bool { + var encoder encoderFunc + var decoder decoderFunc + + if typ.Kind() == reflect.Struct { + encoder = f.encoder + decoder = f.decoder + } else { + for typ.Kind() == reflect.Ptr { + typ = typ.Elem() + encoder = getEncoder(typ) + decoder = getDecoder(typ) + } + if typ.Kind() != reflect.Struct { + return false + } + } + + if reflect.ValueOf(encoder).Pointer() != encodeStructValuePtr { + return false + } + if reflect.ValueOf(decoder).Pointer() != decodeStructValuePtr { + return false + } + + inlinedFields := getFields(typ, tag).List + for _, field := range inlinedFields { + if _, ok := fs.Map[field.name]; ok { + // Don't auto inline if there are shadowed fields. + return false + } + } + + for _, field := range inlinedFields { + field.index = append(f.index, field.index...) + fs.Add(field) + } + return true +} + +type isZeroer interface { + IsZero() bool +} + +func isEmptyValue(v reflect.Value) bool { + kind := v.Kind() + + for kind == reflect.Interface { + if v.IsNil() { + return true + } + v = v.Elem() + kind = v.Kind() + } + + if z, ok := v.Interface().(isZeroer); ok { + return nilable(kind) && v.IsNil() || z.IsZero() + } + + switch kind { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Ptr: + return v.IsNil() + default: + return false + } +} + +func fieldByIndex(v reflect.Value, index []int) (_ reflect.Value, ok bool) { + if len(index) == 1 { + return v.Field(index[0]), true + } + + for i, idx := range index { + if i > 0 { + if v.Kind() == reflect.Ptr { + if v.IsNil() { + return v, false + } + v = v.Elem() + } + } + v = v.Field(idx) + } + + return v, true +} + +func fieldByIndexAlloc(v reflect.Value, index []int) reflect.Value { + if len(index) == 1 { + return v.Field(index[0]) + } + + for i, idx := range index { + if i > 0 { + var ok bool + v, ok = indirectNil(v) + if !ok { + return v + } + } + v = v.Field(idx) + } + + return v +} + +func indirectNil(v reflect.Value) (reflect.Value, bool) { + if v.Kind() == reflect.Ptr { + if v.IsNil() { + if !v.CanSet() { + return v, false + } + elemType := v.Type().Elem() + if elemType.Kind() != reflect.Struct { + return v, false + } + v.Set(reflect.New(elemType)) + } + v = v.Elem() + } + return v, true +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/unsafe.go b/vendor/github.com/vmihailenco/msgpack/v5/unsafe.go new file mode 100644 index 0000000000..192ac47920 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/unsafe.go @@ -0,0 +1,22 @@ +// +build !appengine + +package msgpack + +import ( + "unsafe" +) + +// bytesToString converts byte slice to string. +func bytesToString(b []byte) string { + return *(*string)(unsafe.Pointer(&b)) +} + +// stringToBytes converts string to byte slice. +func stringToBytes(s string) []byte { + return *(*[]byte)(unsafe.Pointer( + &struct { + string + Cap int + }{s, len(s)}, + )) +} diff --git a/vendor/github.com/vmihailenco/msgpack/v5/version.go b/vendor/github.com/vmihailenco/msgpack/v5/version.go new file mode 100644 index 0000000000..1d49337c35 --- /dev/null +++ b/vendor/github.com/vmihailenco/msgpack/v5/version.go @@ -0,0 +1,6 @@ +package msgpack + +// Version is the current release version. +func Version() string { + return "5.3.5" +} diff --git a/vendor/github.com/vmihailenco/tagparser/v2/.travis.yml b/vendor/github.com/vmihailenco/tagparser/v2/.travis.yml new file mode 100644 index 0000000000..7194cd0010 --- /dev/null +++ b/vendor/github.com/vmihailenco/tagparser/v2/.travis.yml @@ -0,0 +1,19 @@ +dist: xenial +language: go + +go: + - 1.14.x + - 1.15.x + - tip + +matrix: + allow_failures: + - go: tip + +env: + - GO111MODULE=on + +go_import_path: github.com/vmihailenco/tagparser + +before_install: + - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.17.1 diff --git a/vendor/github.com/vmihailenco/tagparser/v2/LICENSE b/vendor/github.com/vmihailenco/tagparser/v2/LICENSE new file mode 100644 index 0000000000..3fc93fdff8 --- /dev/null +++ b/vendor/github.com/vmihailenco/tagparser/v2/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) 2019 The github.com/vmihailenco/tagparser Authors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/vmihailenco/tagparser/v2/Makefile b/vendor/github.com/vmihailenco/tagparser/v2/Makefile new file mode 100644 index 0000000000..0b1b59595a --- /dev/null +++ b/vendor/github.com/vmihailenco/tagparser/v2/Makefile @@ -0,0 +1,9 @@ +all: + go test ./... + go test ./... -short -race + go test ./... -run=NONE -bench=. -benchmem + env GOOS=linux GOARCH=386 go test ./... + go vet ./... + go get github.com/gordonklaus/ineffassign + ineffassign . + golangci-lint run diff --git a/vendor/github.com/vmihailenco/tagparser/v2/README.md b/vendor/github.com/vmihailenco/tagparser/v2/README.md new file mode 100644 index 0000000000..c0259de565 --- /dev/null +++ b/vendor/github.com/vmihailenco/tagparser/v2/README.md @@ -0,0 +1,24 @@ +# Opinionated Golang tag parser + +[![Build Status](https://travis-ci.org/vmihailenco/tagparser.png?branch=master)](https://travis-ci.org/vmihailenco/tagparser) +[![GoDoc](https://godoc.org/github.com/vmihailenco/tagparser?status.svg)](https://godoc.org/github.com/vmihailenco/tagparser) + +## Installation + +Install: + +```shell +go get github.com/vmihailenco/tagparser/v2 +``` + +## Quickstart + +```go +func ExampleParse() { + tag := tagparser.Parse("some_name,key:value,key2:'complex value'") + fmt.Println(tag.Name) + fmt.Println(tag.Options) + // Output: some_name + // map[key:value key2:'complex value'] +} +``` diff --git a/vendor/github.com/vmihailenco/tagparser/v2/internal/parser/parser.go b/vendor/github.com/vmihailenco/tagparser/v2/internal/parser/parser.go new file mode 100644 index 0000000000..21a9bc7f74 --- /dev/null +++ b/vendor/github.com/vmihailenco/tagparser/v2/internal/parser/parser.go @@ -0,0 +1,82 @@ +package parser + +import ( + "bytes" + + "github.com/vmihailenco/tagparser/v2/internal" +) + +type Parser struct { + b []byte + i int +} + +func New(b []byte) *Parser { + return &Parser{ + b: b, + } +} + +func NewString(s string) *Parser { + return New(internal.StringToBytes(s)) +} + +func (p *Parser) Bytes() []byte { + return p.b[p.i:] +} + +func (p *Parser) Valid() bool { + return p.i < len(p.b) +} + +func (p *Parser) Read() byte { + if p.Valid() { + c := p.b[p.i] + p.Advance() + return c + } + return 0 +} + +func (p *Parser) Peek() byte { + if p.Valid() { + return p.b[p.i] + } + return 0 +} + +func (p *Parser) Advance() { + p.i++ +} + +func (p *Parser) Skip(skip byte) bool { + if p.Peek() == skip { + p.Advance() + return true + } + return false +} + +func (p *Parser) SkipBytes(skip []byte) bool { + if len(skip) > len(p.b[p.i:]) { + return false + } + if !bytes.Equal(p.b[p.i:p.i+len(skip)], skip) { + return false + } + p.i += len(skip) + return true +} + +func (p *Parser) ReadSep(sep byte) ([]byte, bool) { + ind := bytes.IndexByte(p.b[p.i:], sep) + if ind == -1 { + b := p.b[p.i:] + p.i = len(p.b) + return b, false + } + + b := p.b[p.i : p.i+ind] + p.i += ind + 1 + return b, true +} diff --git a/vendor/github.com/vmihailenco/tagparser/v2/internal/safe.go b/vendor/github.com/vmihailenco/tagparser/v2/internal/safe.go new file mode 100644 index 0000000000..870fe541f0 --- /dev/null +++ b/vendor/github.com/vmihailenco/tagparser/v2/internal/safe.go @@ -0,0 +1,11 @@ +// +build appengine + +package internal + +func BytesToString(b []byte) string { + return string(b) +} + +func StringToBytes(s string) []byte { + return []byte(s) +} diff --git a/vendor/github.com/vmihailenco/tagparser/v2/internal/unsafe.go b/vendor/github.com/vmihailenco/tagparser/v2/internal/unsafe.go new file mode 100644 index 0000000000..f8bc18d911 --- /dev/null +++ b/vendor/github.com/vmihailenco/tagparser/v2/internal/unsafe.go @@ -0,0 +1,22 @@ +// +build !appengine + +package internal + +import ( + "unsafe" +) + +// BytesToString converts byte slice to string. +func BytesToString(b []byte) string { + return *(*string)(unsafe.Pointer(&b)) +} + +// StringToBytes converts string to byte slice. +func StringToBytes(s string) []byte { + return *(*[]byte)(unsafe.Pointer( + &struct { + string + Cap int + }{s, len(s)}, + )) +} diff --git a/vendor/github.com/vmihailenco/tagparser/v2/tagparser.go b/vendor/github.com/vmihailenco/tagparser/v2/tagparser.go new file mode 100644 index 0000000000..5002e6453e --- /dev/null +++ b/vendor/github.com/vmihailenco/tagparser/v2/tagparser.go @@ -0,0 +1,166 @@ +package tagparser + +import ( + "strings" + + "github.com/vmihailenco/tagparser/v2/internal/parser" +) + +type Tag struct { + Name string + Options map[string]string +} + +func (t *Tag) HasOption(name string) bool { + _, ok := t.Options[name] + return ok +} + +func Parse(s string) *Tag { + p := &tagParser{ + Parser: parser.NewString(s), + } + p.parseKey() + return &p.Tag +} + +type tagParser struct { + *parser.Parser + + Tag Tag + hasName bool + key string +} + +func (p *tagParser) setTagOption(key, value string) { + key = strings.TrimSpace(key) + value = strings.TrimSpace(value) + + if !p.hasName { + p.hasName = true + if key == "" { + p.Tag.Name = value + return + } + } + if p.Tag.Options == nil { + p.Tag.Options = make(map[string]string) + } + if key == "" { + p.Tag.Options[value] = "" + } else { + p.Tag.Options[key] = value + } +} + +func (p *tagParser) parseKey() { + p.key = "" + + var b []byte + for p.Valid() { + c := p.Read() + switch c { + case ',': + p.Skip(' ') + p.setTagOption("", string(b)) + p.parseKey() + return + case ':': + p.key = string(b) + p.parseValue() + return + case '\'': + p.parseQuotedValue() + return + default: + b = append(b, c) + } + } + + if len(b) > 0 { + p.setTagOption("", string(b)) + } +} + +func (p *tagParser) parseValue() { + const quote = '\'' + c := p.Peek() + if c == quote { + p.Skip(quote) + p.parseQuotedValue() + return + } + + var b []byte + for p.Valid() { + c = p.Read() + switch c { + case '\\': + b = append(b, p.Read()) + case '(': + b = append(b, c) + b = p.readBrackets(b) + case ',': + p.Skip(' ') + p.setTagOption(p.key, string(b)) + p.parseKey() + return + default: + b = append(b, c) + } + } + p.setTagOption(p.key, string(b)) +} + +func (p *tagParser) readBrackets(b []byte) []byte { + var lvl int +loop: + for p.Valid() { + c := p.Read() + switch c { + case '\\': + b = append(b, p.Read()) + case '(': + b = append(b, c) + lvl++ + case ')': + b = append(b, c) + lvl-- + if lvl < 0 { + break loop + } + default: + b = append(b, c) + } + } + return b +} + +func (p *tagParser) parseQuotedValue() { + const quote = '\'' + var b []byte + for p.Valid() { + bb, ok := p.ReadSep(quote) + if !ok { + b = append(b, bb...) + break + } + + // keep the escaped single-quote, and continue until we've found the + // one that isn't. + if len(bb) > 0 && bb[len(bb)-1] == '\\' { + b = append(b, bb[:len(bb)-1]...) + b = append(b, quote) + continue + } + + b = append(b, bb...) + break + } + + p.setTagOption(p.key, string(b)) + if p.Skip(',') { + p.Skip(' ') + } + p.parseKey() +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 2486a92397..3f36cdedaa 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -380,6 +380,15 @@ github.com/tidepool-org/hydrophone/client # github.com/urfave/cli v1.22.15 ## explicit; go 1.11 github.com/urfave/cli +# github.com/vmihailenco/msgpack/v5 v5.3.5 +## explicit; go 1.11 +github.com/vmihailenco/msgpack/v5 +github.com/vmihailenco/msgpack/v5/msgpcode +# github.com/vmihailenco/tagparser/v2 v2.0.0 +## explicit; go 1.15 +github.com/vmihailenco/tagparser/v2 +github.com/vmihailenco/tagparser/v2/internal +github.com/vmihailenco/tagparser/v2/internal/parser # github.com/xdg-go/pbkdf2 v1.0.0 ## explicit; go 1.9 github.com/xdg-go/pbkdf2 From 387299acc83c726397685aa6184f2e6ce8dbdaa5 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 12 Jul 2024 12:58:47 +1200 Subject: [PATCH 351/413] pull blob user also --- migrations/20231128_jellyfish_migration/utils/data_verify.go | 2 +- migrations/20231128_jellyfish_migration/verify/verify.go | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index aced5fb269..4e6879a2ad 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -129,7 +129,7 @@ func (m *DataVerify) FetchBlobIDs() ([]map[string]interface{}, error) { "client.private.blobId": bson.M{"$exists": true}, }, &options.FindOptions{ Sort: bson.D{{Key: "deviceId", Value: 1}, {Key: "time", Value: 1}}, - Projection: bson.M{"_id": 0, "deviceId": 1, "blobId": "$client.private.blobId"}, + Projection: bson.M{"_id": 0, "deviceId": 1, "blobId": "$client.private.blobId", "_userId": 1, "time": 1}, }) if err != nil { return nil, err diff --git a/migrations/20231128_jellyfish_migration/verify/verify.go b/migrations/20231128_jellyfish_migration/verify/verify.go index 54dc516031..a8ee00d995 100644 --- a/migrations/20231128_jellyfish_migration/verify/verify.go +++ b/migrations/20231128_jellyfish_migration/verify/verify.go @@ -83,7 +83,6 @@ func (m *Verify) RunAndExit() { if err != nil { return err } - log.Println("BLOBS:") for i, v := range ids { log.Printf("%d - %v", i, v) } From 452362e799b5589a8f2a12eed314c7a4b52ea2ab Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 12 Jul 2024 15:41:27 +1200 Subject: [PATCH 352/413] device blob path, check which is largest for finding missing records --- .../utils/data_verify.go | 15 ++++++++++++--- .../20231128_jellyfish_migration/verify/verify.go | 3 ++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 4e6879a2ad..c6f2c698e7 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -144,11 +144,20 @@ func (m *DataVerify) FetchBlobIDs() ([]map[string]interface{}, error) { func getMissing(a []map[string]interface{}, b []map[string]interface{}) []map[string]interface{} { missing := []map[string]interface{}{} - ma := make(map[string]bool, len(a)) - for _, ka := range a { + + more := a + less := b + + if len(b) > len(a) { + more = b + less = a + } + + ma := make(map[string]bool, len(less)) + for _, ka := range less { ma[fmt.Sprintf("%v", ka["deviceTime"])] = true } - for _, kb := range b { + for _, kb := range more { if !ma[fmt.Sprintf("%v", kb["deviceTime"])] { missing = append(missing, kb) } diff --git a/migrations/20231128_jellyfish_migration/verify/verify.go b/migrations/20231128_jellyfish_migration/verify/verify.go index a8ee00d995..cb89f18c39 100644 --- a/migrations/20231128_jellyfish_migration/verify/verify.go +++ b/migrations/20231128_jellyfish_migration/verify/verify.go @@ -84,7 +84,8 @@ func (m *Verify) RunAndExit() { return err } for i, v := range ids { - log.Printf("%d - %v", i, v) + blobPath := fmt.Sprintf("/blobs/%v/%v/", v["_userId"], v["blobId"]) + log.Printf("%d - [%v] %v", i, v["deviceId"], blobPath) } return nil From f2307df1fed23e6a9b1d3ddf69200a3e4efcbc8a Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 16 Jul 2024 13:15:37 +1200 Subject: [PATCH 353/413] use ConvertCompatibleTypes so non-existent diffs not reported --- migrations/20231128_jellyfish_migration/utils/data_verify.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index c6f2c698e7..fe5f32f27d 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -25,7 +25,7 @@ func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[ log.Println("no matching value in the jellyfish data") break } - changelog, err := diff.Diff(platformDatum, jellyfishData[id], diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) + changelog, err := diff.Diff(platformDatum, jellyfishData[id], diff.ConvertCompatibleTypes(), diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) if err != nil { return nil, err } From f5a21903f93dccf7cd1aac712a42a6697b546e15 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 16 Jul 2024 14:27:55 +1200 Subject: [PATCH 354/413] ability to filter out expected differences --- .../utils/data_verify.go | 32 ++++++++++++++++--- .../verify/verify.go | 9 +----- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index fe5f32f27d..5d44666d52 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -18,7 +18,7 @@ type DataVerify struct { dataC *mongo.Collection } -func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[string]interface{}) (map[string]interface{}, error) { +func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[string]interface{}, ignoredPaths ...string) (map[string]interface{}, error) { diffs := map[string]interface{}{} for id, platformDatum := range platformData { if jellyfishData[id] == nil { @@ -30,7 +30,23 @@ func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[ return nil, err } if len(changelog) > 0 { - diffs[fmt.Sprintf("platform_%d", id)] = changelog + + reportChanges := []interface{}{} + + if ignoredPaths != nil { + changelog = changelog.FilterOut(ignoredPaths) + } + + for _, v := range changelog { + // NOTE: many changes reported where From = and To = + if fmt.Sprintf("%v", v.From) == fmt.Sprintf("%v", v.To) { + if v.Type == diff.UPDATE { + continue + } + } + reportChanges = append(reportChanges, v) + } + diffs[fmt.Sprintf("platform_%d", id)] = reportChanges } } return diffs, nil @@ -50,7 +66,7 @@ func NewVerifier(ctx context.Context, dataC *mongo.Collection) (*DataVerify, err return m, nil } -var DatasetTypes = []string{"cbg", "basal", "bolus", "deviceEvent", "wizard", "pumpSettings"} +var DatasetTypes = []string{"cbg", "smbg", "basal", "bolus", "deviceEvent", "wizard", "pumpSettings"} func (m *DataVerify) fetchDataSet(uploadID string, dataTypes []string) (map[string][]map[string]interface{}, error) { if m.dataC == nil { @@ -166,7 +182,12 @@ func getMissing(a []map[string]interface{}, b []map[string]interface{}) []map[st } -func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUploadID string, dataTyes []string, useSubset bool) error { +var dataTypePathIgnored = map[string][]string{ + "smbg": {"raw", "value"}, + "cbg": {"value"}, +} + +func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUploadID string, dataTyes []string) error { if len(dataTyes) == 0 { dataTyes = DatasetTypes @@ -196,7 +217,8 @@ func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUpload writeFileData(pfSet, comparePath, fmt.Sprintf("raw_%s_pf_%s.json", dType, platformUploadID), true) break } - differences, err := CompareDatasets(pfSet, jfSet) + + differences, err := CompareDatasets(pfSet, jfSet, dataTypePathIgnored[dType]...) if err != nil { return err } diff --git a/migrations/20231128_jellyfish_migration/verify/verify.go b/migrations/20231128_jellyfish_migration/verify/verify.go index cb89f18c39..a6235a6147 100644 --- a/migrations/20231128_jellyfish_migration/verify/verify.go +++ b/migrations/20231128_jellyfish_migration/verify/verify.go @@ -25,7 +25,6 @@ type Verify struct { type config struct { mongoURI string findBlobs bool - useSubset bool platformUploadID string jellyfishUploadID string dataTypes string @@ -100,7 +99,7 @@ func (m *Verify) RunAndExit() { return fmt.Errorf("unable to create verification utils : %w", err) } - err = m.verificationUtil.Verify("ref", m.config.platformUploadID, m.config.jellyfishUploadID, strings.Split(m.config.dataTypes, ","), m.config.useSubset) + err = m.verificationUtil.Verify("ref", m.config.platformUploadID, m.config.jellyfishUploadID, strings.Split(m.config.dataTypes, ",")) if err != nil { log.Printf("error running verify : %s", err.Error()) } @@ -150,12 +149,6 @@ func (m *Verify) Initialize() error { Destination: &m.config.findBlobs, Required: false, }, - cli.BoolFlag{ - Name: UseSubsetFlag, - Usage: "use a subset of data to compare", - Destination: &m.config.useSubset, - Required: false, - }, cli.StringFlag{ Name: MongoURIFlag, Usage: "mongo connection URI", From cfbaffde3502560b24f31bc01d1de224107d93ea Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 16 Jul 2024 16:05:34 +1200 Subject: [PATCH 355/413] update tests and filtering --- .../utils/data_verify.go | 26 ++++----- .../utils/data_verify_test.go | 54 ++++++++++++++++--- 2 files changed, 58 insertions(+), 22 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 5d44666d52..522d31f233 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -30,23 +30,15 @@ func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[ return nil, err } if len(changelog) > 0 { - - reportChanges := []interface{}{} - if ignoredPaths != nil { - changelog = changelog.FilterOut(ignoredPaths) - } - - for _, v := range changelog { - // NOTE: many changes reported where From = and To = - if fmt.Sprintf("%v", v.From) == fmt.Sprintf("%v", v.To) { - if v.Type == diff.UPDATE { - continue - } + for _, path := range ignoredPaths { + changelog = changelog.FilterOut([]string{path}) + } + if len(changelog) == 0 { + continue } - reportChanges = append(reportChanges, v) } - diffs[fmt.Sprintf("platform_%d", id)] = reportChanges + diffs[fmt.Sprintf("platform_%d", id)] = changelog } } return diffs, nil @@ -183,8 +175,10 @@ func getMissing(a []map[string]interface{}, b []map[string]interface{}) []map[st } var dataTypePathIgnored = map[string][]string{ - "smbg": {"raw", "value"}, - "cbg": {"value"}, + "smbg": {"raw", "value"}, + "cbg": {"value"}, + "basal": {"rate"}, + "bolus": {"normal"}, } func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUploadID string, dataTyes []string) error { diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify_test.go b/migrations/20231128_jellyfish_migration/utils/data_verify_test.go index 9dc2715da5..c573b9f96e 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify_test.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify_test.go @@ -3,25 +3,67 @@ package utils_test import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/r3labs/diff/v3" "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" - "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils/test" ) var _ = Describe("CompareDatasets", func() { + datasetOne := []map[string]interface{}{ + { + "one": 1, + "value": 2, + }, + { + "three": 3, + "more": true, + }, + } + datasetTwo := []map[string]interface{}{ + { + "one": "one", + "value": 2, + }, + { + "three": 3, + "more": false, + }, + } + It("will genterate a list of differences between two datasets", func() { - jfDataset := test.BulkJellyfishData("test-device-88x89", "test-group-id", "test-user-id-123", 2) - platformDataset := test.BulkJellyfishData("test-device-88x89", "test-group-id_2", "test-user-id-987", 2) - changes, err := utils.CompareDatasets(jfDataset, platformDataset) + changes, err := utils.CompareDatasets(datasetOne, datasetTwo) Expect(err).To(BeNil()) Expect(changes).ToNot(BeEmpty()) }) It("will genterate no differences when the datasets are the same ", func() { - jfDataset := test.BulkJellyfishData("test-device-88x89", "test-group-id", "test-user-id-123", 100) - changes, err := utils.CompareDatasets(jfDataset, jfDataset) + changes, err := utils.CompareDatasets(datasetOne, datasetOne) + Expect(err).To(BeNil()) + Expect(changes).To(BeEmpty()) + }) + + It("changes will contain each diff", func() { + changes, err := utils.CompareDatasets(datasetOne, datasetTwo) + Expect(err).To(BeNil()) + Expect(changes).To(Equal(map[string]interface{}{ + "platform_0": diff.Changelog{{Type: diff.UPDATE, Path: []string{"one"}, From: 1, To: "one"}}, + "platform_1": diff.Changelog{{Type: diff.UPDATE, Path: []string{"more"}, From: true, To: false}}, + })) + }) + + It("can filter based on path", func() { + changes, err := utils.CompareDatasets(datasetOne, datasetTwo, "more") + Expect(err).To(BeNil()) + Expect(changes).To(Equal(map[string]interface{}{ + "platform_0": diff.Changelog{{Type: diff.UPDATE, Path: []string{"one"}, From: 1, To: "one"}}, + })) + }) + + It("can filter multiple based on path", func() { + changes, err := utils.CompareDatasets(datasetOne, datasetTwo, "more", "one") Expect(err).To(BeNil()) Expect(changes).To(BeEmpty()) }) + }) From 7aaced782d52451a5aa42e9a398a20b269067879 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 17 Jul 2024 08:31:11 +1200 Subject: [PATCH 356/413] write blob data to file --- .../utils/data_verify.go | 27 +++++++++++++++---- .../verify/verify.go | 12 +-------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 522d31f233..19dacefa51 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -125,9 +125,9 @@ func (m *DataVerify) fetchDataSet(uploadID string, dataTypes []string) (map[stri return typeSet, nil } -func (m *DataVerify) FetchBlobIDs() ([]map[string]interface{}, error) { +func (m *DataVerify) WriteBlobIDs() error { if m.dataC == nil { - return nil, errors.New("missing data collection") + return errors.New("missing data collection") } blobData := []map[string]interface{}{} @@ -140,14 +140,31 @@ func (m *DataVerify) FetchBlobIDs() ([]map[string]interface{}, error) { Projection: bson.M{"_id": 0, "deviceId": 1, "blobId": "$client.private.blobId", "_userId": 1, "time": 1}, }) if err != nil { - return nil, err + return err } defer dDataCursor.Close(m.ctx) if err := dDataCursor.All(m.ctx, &blobData); err != nil { - return nil, err + return err + } + + type Blob struct { + DeviceID string `json:"deviceId"` + Path string `json:"path"` } - return blobData, nil + + blobs := []Blob{} + + for _, v := range blobData { + blobs = append(blobs, Blob{ + Path: fmt.Sprintf("/blobs/%v/%v/", v["_userId"], v["blobId"]), + DeviceID: fmt.Sprintf("%v", v["deviceId"])}) + } + + blobPath := filepath.Join(".", "_blobs") + log.Printf("blob data written to %s", blobPath) + writeFileData(blobs, blobPath, "device_blobs.json", true) + return nil } func getMissing(a []map[string]interface{}, b []map[string]interface{}) []map[string]interface{} { diff --git a/migrations/20231128_jellyfish_migration/verify/verify.go b/migrations/20231128_jellyfish_migration/verify/verify.go index a6235a6147..45793097fd 100644 --- a/migrations/20231128_jellyfish_migration/verify/verify.go +++ b/migrations/20231128_jellyfish_migration/verify/verify.go @@ -77,17 +77,7 @@ func (m *Verify) RunAndExit() { if err != nil { return fmt.Errorf("unable to create verification utils : %w", err) } - - ids, err := m.verificationUtil.FetchBlobIDs() - if err != nil { - return err - } - for i, v := range ids { - blobPath := fmt.Sprintf("/blobs/%v/%v/", v["_userId"], v["blobId"]) - log.Printf("%d - [%v] %v", i, v["deviceId"], blobPath) - } - - return nil + return m.verificationUtil.WriteBlobIDs() } m.verificationUtil, err = utils.NewVerifier( From db52ff6577dc694f0a92cde5da2e10f872dca2c3 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 17 Jul 2024 16:19:32 +1200 Subject: [PATCH 357/413] format blob data and include helper script --- .../fetch_blobs.sh | 43 +++++++++++++++++++ .../utils/data_verify.go | 7 +-- 2 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 migrations/20231128_jellyfish_migration/fetch_blobs.sh diff --git a/migrations/20231128_jellyfish_migration/fetch_blobs.sh b/migrations/20231128_jellyfish_migration/fetch_blobs.sh new file mode 100644 index 0000000000..2f8a7693fb --- /dev/null +++ b/migrations/20231128_jellyfish_migration/fetch_blobs.sh @@ -0,0 +1,43 @@ +#!/bin/bash +API_ENV=qa2.development +JSON_FILE=$1 +OUTPUT_DIR=$2 + +check_val() { + if [[ -z "$1" ]]; then + echo "missing $2 value" + exit 2 + fi +} + +check_val $JSON_FILE "JSON_FILE" +check_val $OUTPUT_DIR "OUTPUT_DIR" +check_val $SERVER_SECRET "SERVER_SECRET" + +SESSION_TOKEN="$(curl -s -I -X POST -H "X-Tidepool-Server-Secret: $SERVER_SECRET" -H "X-Tidepool-Server-Name: devops" "https://${API_ENV}.tidepool.org/auth/serverlogin" | grep 'x-tidepool-session-token' | sed 's/[^:]*: //')" + +jq -c '.[]' $JSON_FILE | while read i; do + + DEVICE_ID=$(jq -r '.deviceId' <<<"$i") + check_val $DEVICE_ID "DEVICE_ID" + + BLOB_ID=$(jq -r '.blobId' <<<"$i") + check_val $BLOB_ID "BLOB_ID" + + OUTPUT_FILE="$OUTPUT_DIR/$DEVICE_ID"_blob.gz + + check_val $OUTPUT_FILE "OUTPUT_FILE" + + http_response=$(curl -s -o $OUTPUT_FILE -w "%{response_code}" --request GET \ + --url https://${API_ENV}.tidepool.org/v1/blobs/${BLOB_ID}/content \ + --header 'Accept: */*' \ + --header "X-Tidepool-Session-Token: $SESSION_TOKEN") + + if [ $http_response != "200" ]; then + echo "$http_response error downloading blob $BLOB_ID for device $DEVICE_ID" + rm -rf $OUTPUT_FILE + else + echo "status $http_response done downloading blob $BLOB_ID" + fi + +done diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 19dacefa51..7b429e844b 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -135,9 +135,10 @@ func (m *DataVerify) WriteBlobIDs() error { dDataCursor, err := m.dataC.Find(m.ctx, bson.M{ "deviceManufacturers": bson.M{"$in": []string{"Tandem", "Insulet"}}, "client.private.blobId": bson.M{"$exists": true}, + "_active": true, }, &options.FindOptions{ Sort: bson.D{{Key: "deviceId", Value: 1}, {Key: "time", Value: 1}}, - Projection: bson.M{"_id": 0, "deviceId": 1, "blobId": "$client.private.blobId", "_userId": 1, "time": 1}, + Projection: bson.M{"_id": 0, "deviceId": 1, "blobId": "$client.private.blobId", "time": 1}, }) if err != nil { return err @@ -150,14 +151,14 @@ func (m *DataVerify) WriteBlobIDs() error { type Blob struct { DeviceID string `json:"deviceId"` - Path string `json:"path"` + BlobID string `json:"blobId"` } blobs := []Blob{} for _, v := range blobData { blobs = append(blobs, Blob{ - Path: fmt.Sprintf("/blobs/%v/%v/", v["_userId"], v["blobId"]), + BlobID: fmt.Sprintf("%v", v["blobId"]), DeviceID: fmt.Sprintf("%v", v["deviceId"])}) } From eb023c1d7913234ced9bed26288e1ea076b8d35c Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 19 Jul 2024 12:08:05 +1200 Subject: [PATCH 358/413] find missing datum --- .../utils/data_verify.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 7b429e844b..25f492a401 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -179,13 +179,15 @@ func getMissing(a []map[string]interface{}, b []map[string]interface{}) []map[st less = a } - ma := make(map[string]bool, len(less)) - for _, ka := range less { - ma[fmt.Sprintf("%v", ka["deviceTime"])] = true + ma := map[string]bool{} + + for _, datum := range less { + ma[fmt.Sprintf("%v", datum["deviceTime"])] = true } - for _, kb := range more { - if !ma[fmt.Sprintf("%v", kb["deviceTime"])] { - missing = append(missing, kb) + + for _, datum := range more { + if !ma[fmt.Sprintf("%v", datum["deviceTime"])] { + missing = append(missing, datum) } } return missing From aadfec3c86e63a294ad9e5308dd4435276726240 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 22 Jul 2024 11:26:27 +1200 Subject: [PATCH 359/413] tests for finding missing vals --- .../utils/data_verify.go | 5 +- .../utils/data_verify_test.go | 196 +++++++++++++----- 2 files changed, 146 insertions(+), 55 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 25f492a401..cf5baf9e93 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -168,9 +168,8 @@ func (m *DataVerify) WriteBlobIDs() error { return nil } -func getMissing(a []map[string]interface{}, b []map[string]interface{}) []map[string]interface{} { +func GetMissing(a []map[string]interface{}, b []map[string]interface{}) []map[string]interface{} { missing := []map[string]interface{}{} - more := a less := b @@ -225,7 +224,7 @@ func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUpload log.Printf("data written to %s", comparePath) if len(pfSet) != len(jfSet) { log.Printf("NOTE: datasets mismatch platform (%d) vs jellyfish (%d)", len(pfSet), len(jfSet)) - missing := getMissing(pfSet, jfSet) + missing := GetMissing(pfSet, jfSet) writeFileData(missing, comparePath, fmt.Sprintf("missing_%s.json", dType), true) writeFileData(jfSet, comparePath, fmt.Sprintf("raw_%s_jf_%s.json", dType, jellyfishUploadID), true) writeFileData(pfSet, comparePath, fmt.Sprintf("raw_%s_pf_%s.json", dType, platformUploadID), true) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify_test.go b/migrations/20231128_jellyfish_migration/utils/data_verify_test.go index c573b9f96e..d22c7bf766 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify_test.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify_test.go @@ -6,64 +6,156 @@ import ( "github.com/r3labs/diff/v3" "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" + "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils/test" ) -var _ = Describe("CompareDatasets", func() { - - datasetOne := []map[string]interface{}{ - { - "one": 1, - "value": 2, - }, - { - "three": 3, - "more": true, - }, - } - datasetTwo := []map[string]interface{}{ - { - "one": "one", - "value": 2, - }, - { - "three": 3, - "more": false, - }, - } - - It("will genterate a list of differences between two datasets", func() { - changes, err := utils.CompareDatasets(datasetOne, datasetTwo) - Expect(err).To(BeNil()) - Expect(changes).ToNot(BeEmpty()) - }) +var _ = Describe("DataVerify", func() { - It("will genterate no differences when the datasets are the same ", func() { - changes, err := utils.CompareDatasets(datasetOne, datasetOne) - Expect(err).To(BeNil()) - Expect(changes).To(BeEmpty()) - }) + var _ = Describe("CompareDatasets", func() { - It("changes will contain each diff", func() { - changes, err := utils.CompareDatasets(datasetOne, datasetTwo) - Expect(err).To(BeNil()) - Expect(changes).To(Equal(map[string]interface{}{ - "platform_0": diff.Changelog{{Type: diff.UPDATE, Path: []string{"one"}, From: 1, To: "one"}}, - "platform_1": diff.Changelog{{Type: diff.UPDATE, Path: []string{"more"}, From: true, To: false}}, - })) - }) + var datasetOne = []map[string]interface{}{} + var datasetTwo = []map[string]interface{}{} - It("can filter based on path", func() { - changes, err := utils.CompareDatasets(datasetOne, datasetTwo, "more") - Expect(err).To(BeNil()) - Expect(changes).To(Equal(map[string]interface{}{ - "platform_0": diff.Changelog{{Type: diff.UPDATE, Path: []string{"one"}, From: 1, To: "one"}}, - })) - }) + BeforeEach(func() { + + datasetOne = []map[string]interface{}{ + { + "one": 1, + "value": 2, + }, + { + "three": 3, + "more": true, + }, + } + + datasetTwo = []map[string]interface{}{ + { + "one": "one", + "value": 2, + }, + { + "three": 3, + "more": false, + }, + } + + }) + + It("will genterate a list of differences between two datasets", func() { + changes, err := utils.CompareDatasets(datasetOne, datasetTwo) + Expect(err).To(BeNil()) + Expect(changes).ToNot(BeEmpty()) + }) + + It("will genterate no differences when the datasets are the same ", func() { + changes, err := utils.CompareDatasets(datasetOne, datasetOne) + Expect(err).To(BeNil()) + Expect(changes).To(BeEmpty()) + }) + + It("changes will contain each diff", func() { + changes, err := utils.CompareDatasets(datasetOne, datasetTwo) + Expect(err).To(BeNil()) + Expect(changes).To(Equal(map[string]interface{}{ + "platform_0": diff.Changelog{{Type: diff.UPDATE, Path: []string{"one"}, From: 1, To: "one"}}, + "platform_1": diff.Changelog{{Type: diff.UPDATE, Path: []string{"more"}, From: true, To: false}}, + })) + }) + + It("can filter based on path", func() { + changes, err := utils.CompareDatasets(datasetOne, datasetTwo, "more") + Expect(err).To(BeNil()) + Expect(changes).To(Equal(map[string]interface{}{ + "platform_0": diff.Changelog{{Type: diff.UPDATE, Path: []string{"one"}, From: 1, To: "one"}}, + })) + }) + + It("can filter multiple based on path", func() { + changes, err := utils.CompareDatasets(datasetOne, datasetTwo, "more", "one") + Expect(err).To(BeNil()) + Expect(changes).To(BeEmpty()) + }) - It("can filter multiple based on path", func() { - changes, err := utils.CompareDatasets(datasetOne, datasetTwo, "more", "one") - Expect(err).To(BeNil()) - Expect(changes).To(BeEmpty()) }) + var _ = Describe("GetMissing", func() { + + var dOne = []map[string]interface{}{} + var dLarge = []map[string]interface{}{} + var dLargeTwo = []map[string]interface{}{} + BeforeEach(func() { + + dOne = []map[string]interface{}{ + { + "one": 1, + "value": 2, + "deviceTime": "2023-01-18T00:00:00", + }, + { + "three": 3, + "more": true, + "deviceTime": "2023-01-18T01:00:00", + }, + } + + dLargeTwo = []map[string]interface{}{ + { + "one": 1, + "value": 2, + "deviceTime": "2023-01-18T00:00:00", + }, + { + "three": 3, + "more": true, + "deviceTime": "2023-01-18T01:00:00", + }, + { + "four": 44, + "more": true, + "deviceTime": "2023-01-18T02:00:00", + }, + } + + dLarge = test.BulkJellyfishUploadData("test-device-id", "group-id", "user-id", 2112) + + }) + + It("will be empty when the two datasets match for large amount of data ", func() { + missing := utils.GetMissing(dLarge, dLarge) + Expect(missing).To(BeEmpty()) + }) + + It("will return the missing datum when no match", func() { + missing := utils.GetMissing(dOne, dLargeTwo) + Expect(missing).To(Equal([]map[string]interface{}{{ + "four": 44, + "more": true, + "deviceTime": "2023-01-18T02:00:00", + }})) + }) + + var _ = Describe("order of datasets", func() { + + It("shows missing if largest set first", func() { + dLargeTwo = []map[string]interface{}{} + for i := 10; i < len(dLarge); i++ { + dLargeTwo = append(dLargeTwo, dLarge[i]) + } + missing := utils.GetMissing(dLarge, dLargeTwo) + Expect(len(missing)).To(Equal(10)) + }) + + It("shows missing if largest set second", func() { + dLargeTwo = []map[string]interface{}{} + for i := 10; i < len(dLarge); i++ { + dLargeTwo = append(dLargeTwo, dLarge[i]) + } + missing := utils.GetMissing(dLargeTwo, dLarge) + Expect(len(missing)).To(Equal(10)) + + }) + }) + + }) }) From b32d1b9e03e4b068aff6000223f0161a807793d0 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 24 Jul 2024 11:48:35 +1200 Subject: [PATCH 360/413] CompareDatasets and CompareDatasetDatums updates --- .../utils/data_verify.go | 64 +- .../utils/data_verify_test.go | 111 +- .../utils/test/data_verify.go | 20831 ++++++++++++++++ 3 files changed, 20910 insertions(+), 96 deletions(-) create mode 100644 migrations/20231128_jellyfish_migration/utils/test/data_verify.go diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index cf5baf9e93..6c5b900252 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -18,7 +18,7 @@ type DataVerify struct { dataC *mongo.Collection } -func CompareDatasets(platformData []map[string]interface{}, jellyfishData []map[string]interface{}, ignoredPaths ...string) (map[string]interface{}, error) { +func CompareDatasetDatums(platformData []map[string]interface{}, jellyfishData []map[string]interface{}, ignoredPaths ...string) (map[string]interface{}, error) { diffs := map[string]interface{}{} for id, platformDatum := range platformData { if jellyfishData[id] == nil { @@ -168,29 +168,38 @@ func (m *DataVerify) WriteBlobIDs() error { return nil } -func GetMissing(a []map[string]interface{}, b []map[string]interface{}) []map[string]interface{} { - missing := []map[string]interface{}{} - more := a - less := b +func CompareDatasets(platformSet []map[string]interface{}, jellyfishSet []map[string]interface{}) ([]map[string]interface{}, []map[string]interface{}, []map[string]interface{}) { + platformMissing := []map[string]interface{}{} + platformExtras := []map[string]interface{}{} + platformDuplicates := []map[string]interface{}{} + pfCounts := map[string]int{} - if len(b) > len(a) { - more = b - less = a - } + jfCounts := map[string]int{} - ma := map[string]bool{} + for _, jDatum := range jellyfishSet { + jfCounts[fmt.Sprintf("%v", jDatum["deviceTime"])] += 1 + } - for _, datum := range less { - ma[fmt.Sprintf("%v", datum["deviceTime"])] = true + for _, pDatum := range platformSet { + pfCounts[fmt.Sprintf("%v", pDatum["deviceTime"])] += 1 + if pfCounts[fmt.Sprintf("%v", pDatum["deviceTime"])] > 1 { + platformDuplicates = append(platformDuplicates, pDatum) + continue + } + // jellyfish does not have platform dp then its an extra + if jfCounts[fmt.Sprintf("%v", pDatum["deviceTime"])] == 0 { + platformExtras = append(platformExtras, pDatum) + } } - for _, datum := range more { - if !ma[fmt.Sprintf("%v", datum["deviceTime"])] { - missing = append(missing, datum) + for _, jDatum := range jellyfishSet { + if pfCounts[fmt.Sprintf("%v", jDatum["deviceTime"])] >= 1 { + continue } + platformMissing = append(platformMissing, jDatum) } - return missing + return platformMissing, platformDuplicates, platformExtras } var dataTypePathIgnored = map[string][]string{ @@ -222,20 +231,29 @@ func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUpload pfSet := platformDataset[dType] comparePath := filepath.Join(".", "_compare", fmt.Sprintf("%s_%s", platformUploadID, jellyfishUploadID)) log.Printf("data written to %s", comparePath) + missing, duplicates, extras := CompareDatasets(pfSet, jfSet) + if len(missing) > 0 { + writeFileData(missing, comparePath, fmt.Sprintf("platform_missing_%s.json", dType), true) + } + if len(duplicates) > 0 { + writeFileData(duplicates, comparePath, fmt.Sprintf("platform_duplicates_%s.json", dType), true) + } + if len(extras) > 0 { + writeFileData(extras, comparePath, fmt.Sprintf("platform_extra_%s.json", dType), true) + } if len(pfSet) != len(jfSet) { log.Printf("NOTE: datasets mismatch platform (%d) vs jellyfish (%d)", len(pfSet), len(jfSet)) - missing := GetMissing(pfSet, jfSet) - writeFileData(missing, comparePath, fmt.Sprintf("missing_%s.json", dType), true) - writeFileData(jfSet, comparePath, fmt.Sprintf("raw_%s_jf_%s.json", dType, jellyfishUploadID), true) - writeFileData(pfSet, comparePath, fmt.Sprintf("raw_%s_pf_%s.json", dType, platformUploadID), true) + writeFileData(jfSet, comparePath, fmt.Sprintf("raw_%s_jellyfish_%s.json", dType, jellyfishUploadID), true) + writeFileData(pfSet, comparePath, fmt.Sprintf("raw_%s_platform_%s.json", dType, platformUploadID), true) break } - - differences, err := CompareDatasets(pfSet, jfSet, dataTypePathIgnored[dType]...) + differences, err := CompareDatasetDatums(pfSet, jfSet, dataTypePathIgnored[dType]...) if err != nil { return err } - writeFileData(differences, comparePath, fmt.Sprintf("%s_diff.json", dType), true) + if len(differences) > 0 { + writeFileData(differences, comparePath, fmt.Sprintf("%s_datum_diff.json", dType), true) + } } return nil diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify_test.go b/migrations/20231128_jellyfish_migration/utils/data_verify_test.go index d22c7bf766..946b9838df 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify_test.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify_test.go @@ -11,7 +11,7 @@ import ( var _ = Describe("DataVerify", func() { - var _ = Describe("CompareDatasets", func() { + var _ = Describe("CompareDatasetDatums", func() { var datasetOne = []map[string]interface{}{} var datasetTwo = []map[string]interface{}{} @@ -43,19 +43,19 @@ var _ = Describe("DataVerify", func() { }) It("will genterate a list of differences between two datasets", func() { - changes, err := utils.CompareDatasets(datasetOne, datasetTwo) + changes, err := utils.CompareDatasetDatums(datasetOne, datasetTwo) Expect(err).To(BeNil()) Expect(changes).ToNot(BeEmpty()) }) It("will genterate no differences when the datasets are the same ", func() { - changes, err := utils.CompareDatasets(datasetOne, datasetOne) + changes, err := utils.CompareDatasetDatums(datasetOne, datasetOne) Expect(err).To(BeNil()) Expect(changes).To(BeEmpty()) }) It("changes will contain each diff", func() { - changes, err := utils.CompareDatasets(datasetOne, datasetTwo) + changes, err := utils.CompareDatasetDatums(datasetOne, datasetTwo) Expect(err).To(BeNil()) Expect(changes).To(Equal(map[string]interface{}{ "platform_0": diff.Changelog{{Type: diff.UPDATE, Path: []string{"one"}, From: 1, To: "one"}}, @@ -64,7 +64,7 @@ var _ = Describe("DataVerify", func() { }) It("can filter based on path", func() { - changes, err := utils.CompareDatasets(datasetOne, datasetTwo, "more") + changes, err := utils.CompareDatasetDatums(datasetOne, datasetTwo, "more") Expect(err).To(BeNil()) Expect(changes).To(Equal(map[string]interface{}{ "platform_0": diff.Changelog{{Type: diff.UPDATE, Path: []string{"one"}, From: 1, To: "one"}}, @@ -72,89 +72,54 @@ var _ = Describe("DataVerify", func() { }) It("can filter multiple based on path", func() { - changes, err := utils.CompareDatasets(datasetOne, datasetTwo, "more", "one") + changes, err := utils.CompareDatasetDatums(datasetOne, datasetTwo, "more", "one") Expect(err).To(BeNil()) Expect(changes).To(BeEmpty()) }) }) - var _ = Describe("GetMissing", func() { + var _ = Describe("CompareDatasets", func() { - var dOne = []map[string]interface{}{} - var dLarge = []map[string]interface{}{} - var dLargeTwo = []map[string]interface{}{} + It("will have no differences when that same and no dups", func() { + missing, duplicates, extras := utils.CompareDatasets(test.JFBolusSet, test.JFBolusSet) + Expect(len(duplicates)).To(Equal(0)) + Expect(len(extras)).To(Equal(0)) + Expect(len(missing)).To(Equal(0)) + }) - BeforeEach(func() { + It("will find duplicates in the platform dataset", func() { + missing, duplicates, extras := utils.CompareDatasets(test.PlatformBolusSet, test.JFBolusSet) + Expect(len(duplicates)).To(Equal(395)) + Expect(len(extras)).To(Equal(0)) + Expect(len(missing)).To(Equal(0)) + }) - dOne = []map[string]interface{}{ - { - "one": 1, - "value": 2, - "deviceTime": "2023-01-18T00:00:00", - }, - { - "three": 3, - "more": true, - "deviceTime": "2023-01-18T01:00:00", - }, - } + It("will find extras in the platform dataset", func() { - dLargeTwo = []map[string]interface{}{ - { - "one": 1, - "value": 2, - "deviceTime": "2023-01-18T00:00:00", - }, - { - "three": 3, - "more": true, - "deviceTime": "2023-01-18T01:00:00", - }, - { - "four": 44, - "more": true, - "deviceTime": "2023-01-18T02:00:00", - }, + expectedExtra := map[string]interface{}{ + "extra": 3, + "deviceTime": "2023-01-18T12:00:00", } - dLarge = test.BulkJellyfishUploadData("test-device-id", "group-id", "user-id", 2112) - + missing, duplicates, extras := utils.CompareDatasets(append(test.PlatformBolusSet, expectedExtra), test.JFBolusSet) + Expect(len(duplicates)).To(Equal(395)) + Expect(len(extras)).To(Equal(1)) + Expect(extras[0]).To(Equal(expectedExtra)) + Expect(len(missing)).To(Equal(0)) }) - It("will be empty when the two datasets match for large amount of data ", func() { - missing := utils.GetMissing(dLarge, dLarge) - Expect(missing).To(BeEmpty()) - }) + It("will find missing in the platform dataset", func() { - It("will return the missing datum when no match", func() { - missing := utils.GetMissing(dOne, dLargeTwo) - Expect(missing).To(Equal([]map[string]interface{}{{ - "four": 44, - "more": true, - "deviceTime": "2023-01-18T02:00:00", - }})) - }) + expectedMissing := map[string]interface{}{ + "missing": 3, + "deviceTime": "2023-01-18T12:00:00", + } - var _ = Describe("order of datasets", func() { - - It("shows missing if largest set first", func() { - dLargeTwo = []map[string]interface{}{} - for i := 10; i < len(dLarge); i++ { - dLargeTwo = append(dLargeTwo, dLarge[i]) - } - missing := utils.GetMissing(dLarge, dLargeTwo) - Expect(len(missing)).To(Equal(10)) - }) - - It("shows missing if largest set second", func() { - dLargeTwo = []map[string]interface{}{} - for i := 10; i < len(dLarge); i++ { - dLargeTwo = append(dLargeTwo, dLarge[i]) - } - missing := utils.GetMissing(dLargeTwo, dLarge) - Expect(len(missing)).To(Equal(10)) - - }) + missing, duplicates, extras := utils.CompareDatasets(test.PlatformBolusSet, append(test.JFBolusSet, expectedMissing)) + Expect(len(duplicates)).To(Equal(395)) + Expect(len(extras)).To(Equal(0)) + Expect(len(missing)).To(Equal(1)) + Expect(missing[0]).To(Equal(expectedMissing)) }) }) diff --git a/migrations/20231128_jellyfish_migration/utils/test/data_verify.go b/migrations/20231128_jellyfish_migration/utils/test/data_verify.go new file mode 100644 index 0000000000..470de45365 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/utils/test/data_verify.go @@ -0,0 +1,20831 @@ +package test + +var JFBolusSet = []map[string]interface{}{ + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-11T05:48:32", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-11T08:48:43", + "normal": 2.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-11T17:07:35", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-11T17:48:17", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-11T22:16:32", + "expectedNormal": 6, + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T02:48:01", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T02:57:56", + "normal": 2.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T03:45:23", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T04:02:33", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T04:07:54", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T12:10:52", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T13:43:31", + "normal": 0.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T18:55:53", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T22:06:00", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-13T00:07:54", + "normal": 6.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-13T15:36:15", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-13T19:15:32", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-13T23:32:46", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-14T02:56:18", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-14T15:05:16", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-14T18:45:59", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-14T21:06:30", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-15T02:10:44", + "expectedNormal": 6, + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-15T10:11:52", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-15T10:21:08", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-15T10:52:13", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-15T18:51:32", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-15T20:32:07", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-15T20:43:33", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-15T21:26:55", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-16T07:56:57", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-16T15:32:09", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-16T16:04:19", + "expectedNormal": 3.7, + "normal": 0.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-16T16:04:45", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-16T16:23:41", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-16T16:35:34", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-16T16:58:46", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-16T22:04:48", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T07:49:22", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T07:58:22", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T08:31:44", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T09:25:59", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T15:19:35", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T15:41:16", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T16:13:32", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T16:51:39", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T17:36:34", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T22:24:30", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-18T00:26:16", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-18T00:57:05", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-18T09:39:10", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-18T13:26:16", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-18T15:56:31", + "normal": 0.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-18T16:46:24", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-18T17:16:59", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-19T01:21:09", + "normal": 2.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-19T01:51:44", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-19T18:01:16", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-19T19:01:35", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-19T22:24:42", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-19T22:27:54", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-19T23:16:39", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-20T11:50:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-20T13:36:40", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-20T18:31:12", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-20T19:04:49", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-20T19:13:53", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-21T14:16:39", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-22T00:12:03", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-22T13:54:39", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-22T20:02:33", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-22T20:09:02", + "normal": 7.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-22T20:42:46", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-22T20:51:20", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-23T14:51:38", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-23T17:40:56", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-24T10:57:40", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-24T13:49:15", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-24T20:29:08", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-24T23:20:14", + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T02:11:25", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T03:41:15", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T03:49:26", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T11:34:54", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T11:36:30", + "expectedNormal": 3.7, + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T11:39:54", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T18:55:44", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T21:00:32", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T21:56:23", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T22:40:16", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-26T00:47:19", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-26T11:19:24", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-26T18:22:46", + "normal": 9.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-26T20:06:31", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-26T21:00:39", + "normal": 4.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-27T00:43:11", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-27T00:54:23", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-27T01:21:34", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-27T07:02:47", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-27T08:20:19", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-27T11:57:25", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-27T18:36:04", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-27T20:18:11", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-28T10:55:51", + "normal": 10.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-28T13:31:27", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-28T17:47:15", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-28T18:58:25", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-28T20:20:09", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T05:47:36", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T11:04:51", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T11:17:10", + "expectedNormal": 5, + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T11:17:44", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T11:59:21", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T12:33:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T16:04:51", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T18:22:02", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T20:35:15", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-30T00:19:10", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-30T01:14:53", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-30T11:38:04", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-30T14:10:30", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-30T18:11:40", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-30T19:40:37", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-30T22:39:58", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-01T09:55:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-01T12:02:23", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-01T12:11:07", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-01T15:03:11", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-01T23:36:08", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-02T13:42:27", + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-03T08:36:32", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-03T12:46:16", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-03T14:31:00", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-03T19:01:03", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-03T19:13:12", + "duration": 3600000, + "extended": 1.35, + "normal": 3.25, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-03T23:09:17", + "expectedNormal": 5.6, + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-04T01:32:34", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-04T13:31:48", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-04T23:45:20", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-05T05:38:22", + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-05T13:05:36", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-05T18:04:44", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-05T22:31:49", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-06T09:05:49", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-06T19:44:34", + "normal": 3.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-07T11:30:47", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-07T17:39:58", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-08T09:36:46", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-08T12:09:06", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-08T13:51:33", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-08T22:47:22", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-08T23:06:37", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-08T23:34:05", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-09T11:51:03", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-09T18:28:48", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-09T18:41:43", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-09T19:46:42", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-09T22:41:34", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-10T03:05:28", + "normal": 1.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-10T11:34:38", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-10T14:55:50", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-10T15:23:08", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-10T19:28:56", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-10T21:16:11", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-10T22:17:25", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-11T14:30:42", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-11T19:17:18", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-12T13:15:43", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-12T14:37:19", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-12T20:45:23", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-12T21:17:50", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-12T22:07:50", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-12T23:57:33", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-13T10:28:04", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-13T17:42:12", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-14T04:31:16", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-14T09:40:01", + "normal": 3.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-14T15:57:40", + "normal": 2.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-14T17:26:58", + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-15T05:49:43", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-15T09:42:54", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-15T15:42:11", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-15T17:58:05", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-15T20:36:40", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-15T21:54:57", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-16T02:10:54", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-16T05:18:35", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-16T17:03:43", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-16T21:17:40", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-16T21:27:12", + "expectedNormal": 1.8, + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-17T15:02:37", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-18T08:53:51", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-18T14:07:21", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-19T00:37:12", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-20T22:52:22", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-21T16:04:44", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-21T17:31:36", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-22T20:34:13", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T00:32:29", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T02:01:53", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T13:25:12", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T14:45:29", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T15:17:41", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T15:27:27", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T20:51:42", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T22:28:05", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-24T15:45:49", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-24T17:30:54", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-25T03:24:31", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-25T17:51:24", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-25T18:17:02", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-25T18:44:42", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-25T19:06:09", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-26T04:38:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-26T21:52:20", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-26T22:10:35", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-27T00:35:55", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-27T12:09:08", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-27T13:12:31", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-27T22:06:04", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-27T23:57:59", + "normal": 8.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-28T13:41:05", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-28T21:53:48", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-28T22:38:58", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-28T23:35:34", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-29T01:10:10", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-29T13:28:49", + "normal": 7.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-29T15:31:09", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-29T15:47:25", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-29T20:49:26", + "normal": 10.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-29T23:31:22", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T01:14:51", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T10:07:54", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T14:41:41", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T15:36:28", + "normal": 0.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T17:21:07", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T17:47:07", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T19:43:22", + "normal": 10.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T21:42:19", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T23:34:45", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T23:57:13", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-31T14:15:24", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-31T15:37:20", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-31T16:37:23", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-31T20:22:35", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-31T22:50:28", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-01T00:18:37", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-01T03:28:56", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-01T08:23:20", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-01T17:09:58", + "normal": 5.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-01T20:29:55", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-01T21:39:29", + "normal": 11.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T01:37:45", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T09:05:27", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T09:28:02", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T15:17:44", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T17:05:07", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T21:57:29", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T22:31:41", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T23:58:14", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-03T06:23:16", + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-03T13:07:10", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-03T17:36:24", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-03T19:19:53", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-04T20:39:32", + "normal": 12.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-04T23:27:30", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-05T11:26:40", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-05T14:39:47", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-05T21:24:08", + "normal": 12.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-05T23:47:57", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-06T10:29:13", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-07T02:43:11", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-07T15:29:23", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-07T15:53:38", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-08T00:50:58", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-08T02:22:40", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-08T10:49:22", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-08T12:10:15", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-08T16:06:15", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-08T21:00:55", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-08T22:52:11", + "normal": 13.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-09T06:48:05", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-09T11:57:20", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-09T14:50:09", + "expectedNormal": 7.1, + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-09T15:09:57", + "expectedNormal": 5.3, + "normal": 0, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-09T15:10:07", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-09T15:45:24", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-09T19:08:06", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-10T00:20:48", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-10T09:57:07", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-10T15:19:38", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-10T19:51:35", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-10T21:04:03", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-11T17:21:27", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-11T23:50:01", + "normal": 9.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-12T14:21:27", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-13T01:22:50", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-13T09:16:42", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-13T09:45:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-13T17:59:12", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-13T19:51:42", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-14T01:09:36", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-14T15:27:34", + "normal": 6.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-14T15:37:30", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-14T19:52:15", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-14T22:44:38", + "normal": 11, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-14T23:04:59", + "expectedNormal": 8.7, + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-15T08:08:01", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-15T17:50:26", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-15T18:22:34", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-15T22:12:43", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-16T05:28:57", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-16T19:06:03", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-18T00:44:27", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-18T15:16:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-18T21:34:19", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-19T15:18:48", + "normal": 7.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-19T18:24:25", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-19T21:40:18", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-20T01:57:09", + "normal": 5.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-20T05:21:15", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-20T14:43:26", + "normal": 2.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-20T20:23:29", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-20T23:15:21", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-21T01:47:25", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-21T16:32:58", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-21T21:12:41", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-22T13:07:23", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-22T13:24:37", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-22T13:38:43", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-22T14:23:46", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-23T00:01:17", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-23T02:53:10", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-23T10:26:09", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-23T12:45:53", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-23T19:04:33", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-24T02:03:30", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-24T08:42:05", + "normal": 3.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-24T09:11:28", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-24T13:05:25", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-24T16:20:41", + "normal": 0.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-24T19:39:24", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-24T22:58:57", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-25T09:05:32", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-25T09:15:49", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-25T10:05:32", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-25T15:20:46", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-26T00:34:00", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-26T00:40:32", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-26T17:42:21", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-27T00:26:46", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-27T01:56:53", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-27T15:00:57", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-27T16:30:36", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-28T00:07:24", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-28T04:04:35", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-28T11:06:58", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-28T12:05:56", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-28T17:32:14", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-28T22:51:31", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-29T09:24:11", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-29T11:48:49", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-31T17:35:53", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-01T22:39:45", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-01T23:11:22", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-02T05:32:22", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-02T13:53:59", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-02T15:01:02", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-03T11:47:19", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-03T17:52:13", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-04T00:51:30", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-04T01:35:03", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-04T10:23:28", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-05T00:40:31", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-05T22:10:18", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-06T00:30:31", + "duration": 9000000, + "extended": 2.4, + "normal": 0.1, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-06T11:27:46", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-06T12:24:47", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-06T21:00:06", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-06T21:26:09", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-06T22:30:08", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-07T01:20:24", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-07T15:08:42", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-07T17:35:21", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-08T00:40:52", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-08T04:05:56", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-08T04:08:07", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-08T20:24:34", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-08T21:17:19", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-09T03:41:21", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-09T03:43:00", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-09T15:27:27", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-09T16:50:23", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-10T00:06:05", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-10T07:13:02", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-10T10:23:08", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-11T01:16:30", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-11T13:20:10", + "normal": 1.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-11T17:04:18", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-11T19:38:24", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-11T20:40:19", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-11T22:22:57", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-11T23:03:25", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-12T10:31:15", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-12T10:47:00", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-12T17:15:24", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-12T22:52:54", + "duration": 5400000, + "extended": 3.6, + "normal": 0.4, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-12T23:37:16", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-13T03:06:20", + "expectedNormal": 2.4, + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-13T04:51:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-13T19:40:33", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-13T20:05:03", + "normal": 0.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-14T17:20:11", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-14T17:56:34", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-15T01:56:38", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-15T17:29:22", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-16T09:23:19", + "normal": 2.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-17T11:56:27", + "normal": 0.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-18T00:34:51", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-18T04:32:23", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-18T12:15:36", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-18T12:56:37", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-18T20:43:52", + "normal": 9.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-19T03:06:10", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-19T17:37:52", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-19T18:33:24", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-19T22:24:06", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-19T23:15:16", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-19T23:57:50", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-20T11:27:44", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-20T12:13:32", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-20T17:12:58", + "normal": 7.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-20T23:25:38", + "normal": 4.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-21T18:12:48", + "normal": 4.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-21T23:02:43", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-22T05:11:08", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-22T12:46:46", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-22T18:44:55", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-22T23:47:30", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-23T15:22:30", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-24T01:28:13", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-24T04:50:59", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-24T10:06:16", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-24T10:57:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-24T16:20:38", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-24T20:57:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-24T21:10:06", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-25T01:46:05", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-25T03:01:41", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-25T12:45:34", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-25T16:35:50", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-25T16:43:09", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-26T14:50:38", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-26T23:18:20", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-27T19:10:37", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-27T19:56:05", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-27T20:05:22", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-27T20:33:26", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-01T11:06:45", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-01T13:38:00", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-01T17:26:06", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-02T05:10:59", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-02T14:53:50", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-02T15:15:41", + "duration": 7200000, + "extended": 4, + "normal": 2.65, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-02T17:55:24", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-02T21:27:07", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-03T02:23:28", + "normal": 3.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-03T07:55:24", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-03T13:31:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-03T17:33:40", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-04T01:00:34", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-04T09:51:54", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-04T13:59:53", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-04T14:53:15", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-04T17:26:51", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-04T19:38:13", + "normal": 8.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-04T23:09:52", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-04T23:57:26", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-05T03:09:50", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-05T14:54:46", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-05T18:29:31", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-06T00:34:35", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-06T01:21:36", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-06T06:12:45", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-06T19:38:19", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-07T08:26:18", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-07T10:24:27", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-07T16:59:43", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-07T22:10:21", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-07T23:47:40", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-08T00:47:32", + "duration": 10800000, + "extended": 1.65, + "subType": "square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-08T17:20:24", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-08T23:16:45", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-09T09:43:12", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-09T19:36:18", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-09T21:47:07", + "normal": 11, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-09T22:28:29", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-10T00:56:27", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-10T05:18:33", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-10T10:09:03", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-10T19:08:41", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-10T19:30:42", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-10T21:00:08", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-10T21:11:26", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-11T00:12:25", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-11T03:50:32", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-11T09:48:55", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-11T17:56:25", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-11T21:45:42", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-11T23:48:21", + "normal": 7.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-11T23:59:24", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-12T11:02:19", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-12T14:13:44", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-12T23:30:03", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-13T00:01:21", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-13T08:23:02", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-13T15:29:58", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-13T16:25:10", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-14T01:00:14", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-14T01:48:33", + "duration": 7200000, + "extended": 5, + "subType": "square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-14T08:26:33", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-14T09:15:40", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-14T21:17:36", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-14T21:36:42", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-15T01:00:44", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-15T12:10:00", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-15T13:36:53", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-15T21:24:43", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-15T22:46:02", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-16T19:49:33", + "normal": 12.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-17T15:56:01", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-18T10:02:04", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-18T15:29:15", + "normal": 6.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-18T16:27:25", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-18T21:15:02", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-19T06:28:44", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-19T15:28:25", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-19T22:15:08", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-20T08:14:49", + "duration": 3600000, + "extended": 1.5, + "normal": 0.5, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-20T12:02:19", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-20T13:19:06", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-20T16:07:19", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-20T19:43:27", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-20T20:56:53", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-21T00:32:48", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-21T14:39:05", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-21T21:09:21", + "normal": 12, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-21T22:14:04", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-22T03:19:52", + "expectedNormal": 5.15, + "normal": 0.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-22T03:20:35", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-22T10:57:48", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-22T16:15:49", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-22T23:32:14", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-23T03:44:48", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-23T10:03:49", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-23T12:03:21", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-23T12:08:31", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-23T17:28:19", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-23T18:10:06", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-23T22:45:10", + "normal": 6.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-23T23:57:11", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-24T01:52:51", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-24T04:04:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-24T10:09:10", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-24T15:22:15", + "normal": 9.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-24T15:59:21", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-24T18:45:12", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-25T03:44:15", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-25T04:12:56", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-25T13:25:50", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-25T15:47:08", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-25T16:27:53", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-25T17:26:51", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-26T01:03:51", + "normal": 9.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-26T04:48:39", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-26T15:52:08", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-26T18:11:28", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-26T21:42:00", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-26T23:21:43", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-27T13:11:38", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-27T13:27:58", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-27T13:43:12", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-27T14:19:41", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-28T01:21:26", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-28T02:49:55", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-28T12:09:39", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-28T21:12:56", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-29T01:42:57", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-29T12:10:07", + "normal": 8.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-29T20:29:43", + "normal": 8.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-29T23:08:20", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-29T23:23:56", + "expectedNormal": 2, + "normal": 0.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-29T23:24:13", + "expectedNormal": 3.8, + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-29T23:25:03", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-30T09:17:33", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-30T11:41:40", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-30T18:46:16", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-30T22:26:35", + "normal": 7.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-31T09:34:04", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-31T11:02:09", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-31T18:03:31", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-01T13:35:12", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-01T19:00:43", + "expectedNormal": 5.5, + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-02T11:24:01", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-03T00:24:02", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-03T04:46:03", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-03T13:58:14", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-03T15:41:52", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-03T22:48:16", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-03T22:53:19", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-03T23:37:06", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-04T17:49:44", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-04T18:25:58", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-04T20:06:51", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-04T20:50:31", + "expectedNormal": 6.5, + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-04T21:47:42", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-05T11:10:22", + "normal": 8.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-05T13:57:52", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-05T14:41:02", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-05T19:55:35", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-05T20:07:23", + "normal": 6.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-05T23:10:52", + "normal": 10.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-06T17:04:13", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-07T00:30:35", + "normal": 13, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-07T11:30:23", + "expectedNormal": 11.3, + "normal": 7.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-07T13:39:36", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-07T15:31:20", + "normal": 7.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-07T17:03:27", + "normal": 6.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-07T19:36:38", + "normal": 11.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T02:04:38", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T11:36:22", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T15:35:43", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T16:36:54", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T17:06:19", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T18:36:43", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T20:45:53", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T21:43:56", + "normal": 5.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T22:27:26", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-09T13:34:32", + "normal": 4.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-09T23:51:42", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-10T11:33:52", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-10T15:06:31", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-10T16:39:01", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-10T23:28:10", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-10T23:56:06", + "normal": 3.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-11T08:31:34", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-11T14:14:04", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-11T21:33:10", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-12T13:11:06", + "normal": 5.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-12T15:22:32", + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-12T20:37:48", + "duration": 3600000, + "extended": 1.4, + "normal": 4.1, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-13T07:00:52", + "normal": 2.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-13T11:55:34", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-13T15:38:33", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-13T16:43:21", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-13T22:25:40", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-13T23:43:31", + "duration": 3600000, + "extended": 3, + "normal": 4.5, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-14T07:24:30", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-14T11:26:07", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-14T14:02:33", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-14T16:13:29", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-14T16:21:37", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-15T04:30:42", + "normal": 2.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-15T11:27:28", + "normal": 9.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-15T21:09:40", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-15T21:29:47", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-16T08:42:28", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-16T09:08:02", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-16T18:50:11", + "normal": 7.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-16T22:19:29", + "normal": 8.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-17T07:49:58", + "expectedNormal": 6.25, + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-17T10:22:10", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-17T15:38:57", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-17T16:53:15", + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-17T23:01:44", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-17T23:17:46", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-18T03:36:54", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-18T08:15:40", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-18T13:03:08", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-18T22:49:11", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-19T10:49:57", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-19T12:47:07", + "normal": 7.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-19T18:51:49", + "normal": 0.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T00:34:12", + "normal": 4.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T11:55:56", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T12:21:25", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T12:25:59", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T12:40:44", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T16:51:52", + "normal": 5.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T17:13:53", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T18:53:57", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T21:13:02", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T21:17:28", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T22:56:20", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-21T05:00:30", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-21T14:57:12", + "expectedNormal": 5.7, + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-21T17:25:57", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-21T19:55:14", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-21T20:21:02", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-21T20:48:12", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-21T23:36:01", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-22T00:17:02", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-22T07:20:00", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-22T09:32:51", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-22T15:34:54", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-22T17:17:07", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-22T18:33:33", + "normal": 8.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-22T19:56:36", + "normal": 4.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-22T21:38:22", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-23T14:44:27", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-23T16:39:55", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-23T17:17:36", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-23T18:45:04", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-23T21:54:57", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-23T23:08:34", + "expectedNormal": 2.5, + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-23T23:30:54", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-24T10:55:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-24T16:10:07", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-24T18:45:06", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-24T21:29:29", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-25T02:05:38", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-25T16:31:35", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-25T16:52:59", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-25T23:23:29", + "normal": 9.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-26T10:15:03", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-26T13:15:18", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-26T13:53:04", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-26T15:43:54", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-26T20:06:36", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-27T12:42:46", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-27T15:48:19", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-27T15:53:18", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-27T23:14:39", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-28T02:49:38", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-28T14:15:39", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-28T15:36:19", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-28T17:22:40", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-28T23:33:46", + "normal": 6.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-29T12:43:56", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-29T14:24:57", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-29T16:00:35", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-29T22:51:00", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-30T16:41:59", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-30T23:51:20", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-01T00:40:06", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-01T02:19:29", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-01T15:47:28", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-01T17:58:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-02T01:01:32", + "duration": 5400000, + "extended": 1.85, + "normal": 0.05, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-02T14:35:54", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-02T16:30:55", + "normal": 1.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-02T18:03:13", + "normal": 2.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-02T18:30:32", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-02T22:44:03", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-03T13:28:40", + "normal": 7.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-03T22:38:40", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-04T06:40:11", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-04T12:09:02", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-04T12:42:38", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-04T13:58:04", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-04T19:31:20", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-05T13:12:58", + "normal": 5.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-05T17:02:00", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-05T22:18:24", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-06T12:34:16", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-06T20:28:21", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-06T21:05:28", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-07T10:11:40", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-07T12:47:09", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-07T20:59:51", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-07T21:46:06", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-08T07:29:03", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-08T13:44:00", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-08T20:00:38", + "normal": 2.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-09T14:28:06", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-09T23:50:14", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-10T10:13:12", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-10T12:28:54", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-10T14:38:18", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-10T18:48:40", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-10T19:22:11", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-10T20:10:02", + "normal": 0.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-10T20:43:41", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-11T02:11:06", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-11T15:22:52", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-11T19:51:32", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-11T20:01:17", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-11T21:07:27", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-11T22:40:53", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-12T00:51:28", + "normal": 5.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-12T09:31:50", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-12T17:24:32", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-12T17:31:58", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-12T19:20:54", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-12T20:09:19", + "normal": 6.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-12T23:53:39", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-13T06:04:08", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-13T09:33:30", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-13T10:02:35", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-13T13:25:22", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-13T14:39:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-13T21:27:31", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-13T21:49:54", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-14T06:30:45", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-14T17:13:50", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-14T19:51:30", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-15T02:59:12", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-15T18:34:17", + "normal": 8.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-15T20:03:48", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-15T20:13:10", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-15T21:08:56", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-15T21:38:31", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-16T11:44:10", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-16T13:54:41", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-16T17:33:07", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-16T18:59:52", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-16T22:40:06", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-17T10:47:43", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-17T17:33:07", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-17T21:09:30", + "normal": 8.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-17T21:38:23", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-18T14:40:29", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-18T16:20:15", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-18T17:18:29", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-18T21:04:49", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-19T08:29:53", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-19T10:55:07", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-19T13:03:51", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-19T20:15:44", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-19T20:28:37", + "normal": 10.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-20T00:18:39", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-20T01:24:17", + "normal": 0.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-20T07:49:45", + "normal": 0.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-20T11:51:55", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-20T12:13:22", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-20T14:57:44", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-20T18:03:00", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-21T10:31:41", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-21T13:57:19", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-21T19:23:59", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-21T22:46:23", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-22T09:51:09", + "normal": 9.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-22T19:41:23", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-22T22:49:19", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-23T07:43:22", + "normal": 5.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-23T15:05:51", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-23T16:43:30", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-23T20:24:21", + "normal": 10.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-23T20:36:41", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-24T01:31:04", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-24T12:17:15", + "normal": 4.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-24T13:52:54", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-24T22:00:26", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-24T22:31:42", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-25T07:08:36", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-25T09:25:26", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-25T10:43:07", + "duration": 3600000, + "extended": 2.15, + "normal": 6.35, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-25T15:29:54", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-25T19:28:58", + "normal": 4.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-25T21:48:56", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-26T07:47:05", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-26T15:09:57", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-26T15:23:19", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-26T19:21:32", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-26T22:54:32", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-27T08:07:50", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-27T12:47:09", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-27T13:23:20", + "normal": 1.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-27T17:55:40", + "normal": 7.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-27T19:30:40", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-27T22:57:00", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-28T02:25:19", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-28T16:54:27", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-28T17:18:04", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-28T19:15:15", + "normal": 6.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-28T20:51:16", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-28T23:10:50", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-29T01:18:06", + "normal": 1.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-29T14:47:42", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-29T16:34:10", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-29T22:26:32", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-31T04:03:49", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-31T10:56:21", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-31T13:27:12", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-31T19:41:58", + "normal": 2.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-31T21:08:12", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-31T22:40:45", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-31T23:11:40", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-01T11:33:30", + "normal": 2.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-01T20:49:42", + "normal": 5.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-01T23:31:41", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-02T02:42:26", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-02T03:08:32", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-02T12:36:04", + "normal": 7.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-02T13:23:44", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-02T20:07:26", + "normal": 7.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-03T15:01:33", + "normal": 0.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-03T15:46:39", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-03T16:41:33", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-03T17:18:38", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-03T17:43:38", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-04T10:16:53", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-04T14:50:00", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-04T16:14:19", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-04T19:21:41", + "normal": 8.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-04T23:46:41", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-05T00:44:34", + "expectedNormal": 2, + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-05T01:02:58", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-05T12:01:09", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-05T12:23:18", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-05T12:51:54", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-05T15:39:48", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-05T21:29:36", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-06T04:21:34", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-06T08:53:58", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-07T15:08:48", + "normal": 0.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-10T19:54:26", + "normal": 7.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-08T15:53:04", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-08T22:22:31", + "normal": 7.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-08T22:47:20", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-09T15:51:36", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-10T00:59:27", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-10T10:23:36", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-10T18:30:44", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-10T18:39:41", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-10T19:47:34", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-11T13:53:18", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-11T20:58:05", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-12T00:35:54", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-12T13:04:51", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-12T17:37:35", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-12T19:09:48", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-12T19:34:40", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-13T00:02:43", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-13T00:11:41", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-13T08:33:39", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-13T20:19:52", + "duration": 1800000, + "extended": 2.55, + "normal": 0.6, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-14T16:44:31", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-14T22:46:55", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-15T00:28:57", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-15T08:51:33", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-15T11:33:53", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-15T19:09:51", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-16T17:02:11", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-16T18:49:50", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-16T20:22:02", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-17T11:14:04", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-17T19:29:27", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-18T06:45:25", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-18T15:28:35", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-18T16:20:17", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-18T16:50:44", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-18T22:16:57", + "duration": 3600000, + "extended": 4.2, + "normal": 2.8, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-19T07:18:23", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-19T18:51:48", + "normal": 4.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-20T08:50:29", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-20T11:19:38", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-20T15:42:53", + "duration": 1800000, + "extended": 0.45, + "normal": 1.3, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-20T17:25:24", + "duration": 3600000, + "extended": 0.75, + "normal": 3, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-20T21:38:30", + "duration": 3600000, + "extended": 2.85, + "normal": 6.55, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-21T11:54:08", + "duration": 3600000, + "extended": 2.8, + "normal": 2.8, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-21T14:39:04", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-21T18:23:31", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-21T19:29:16", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-21T20:00:12", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-21T21:40:40", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-21T23:42:55", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-22T00:24:30", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-22T08:20:59", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-22T21:37:44", + "duration": 3600000, + "extended": 1.2, + "normal": 4.8, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-22T22:25:47", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-22T23:37:05", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-23T07:32:39", + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-23T19:09:07", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-23T20:27:18", + "duration": 3600000, + "extended": 1.75, + "normal": 3.25, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-23T22:28:35", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-23T23:23:04", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T08:19:28", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T09:04:06", + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T10:00:56", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T18:30:46", + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T19:44:10", + "normal": 1.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T20:32:30", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T20:39:38", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-25T09:17:23", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-25T16:59:11", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-25T17:49:12", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-25T19:55:43", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-26T03:01:17", + "normal": 1.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-26T07:05:35", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-26T09:44:50", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-27T16:48:06", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-27T17:13:45", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-27T17:57:18", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-27T22:06:32", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-28T15:46:44", + "normal": 6.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-28T16:18:13", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-28T16:23:18", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-28T16:28:41", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-29T18:27:23", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-30T12:43:51", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-01T17:46:55", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-01T18:30:32", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-01T18:51:38", + "normal": 4.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-02T00:15:19", + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-02T06:49:58", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-02T18:35:00", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-03T12:03:51", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-03T12:50:24", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-03T17:08:12", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-03T17:41:00", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-03T19:08:04", + "expectedNormal": 2, + "normal": 0.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-03T19:08:18", + "normal": 0.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-04T01:21:22", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-04T14:10:31", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-04T17:59:30", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-04T19:21:37", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-04T19:25:51", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-04T20:09:01", + "normal": 7.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-05T02:02:39", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-05T02:36:40", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-05T13:58:30", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-05T17:17:54", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-05T23:40:50", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-06T01:28:33", + "normal": 3.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-06T14:59:11", + "normal": 2.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-06T20:26:50", + "duration": 3600000, + "extended": 2, + "normal": 6, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-07T00:48:50", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-07T14:09:43", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-07T16:02:12", + "duration": 5400000, + "extended": 3.25, + "normal": 9.75, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-08T18:17:26", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-08T18:29:06", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-08T20:29:43", + "normal": 5.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-08T23:53:16", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-09T12:19:24", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-09T16:27:30", + "duration": 3600000, + "extended": 1, + "normal": 5.65, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-09T17:50:34", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-10T00:25:49", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-10T17:43:21", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-10T18:08:03", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-11T13:06:32", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-11T19:37:52", + "normal": 7.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-12T00:07:01", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-12T00:42:51", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-12T07:40:06", + "normal": 3.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-12T08:50:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-12T16:09:42", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-12T21:45:57", + "normal": 6.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-13T10:56:43", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-13T11:42:47", + "normal": 1.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-13T16:33:50", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-13T18:21:41", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-13T22:13:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-13T22:19:30", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-13T22:48:14", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-13T23:08:30", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-14T14:31:41", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-14T15:53:20", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-14T17:37:39", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-14T18:15:11", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-14T20:29:30", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-15T12:18:56", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-15T14:09:52", + "normal": 4.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-15T17:23:04", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-15T21:15:01", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-15T21:44:35", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-15T22:12:37", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-15T22:57:20", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-15T22:58:49", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-16T09:35:57", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-16T11:31:07", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-16T15:12:49", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-16T15:41:21", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-16T21:04:38", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-17T03:22:39", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-17T14:09:57", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-17T16:29:43", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-18T05:26:35", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-18T08:03:17", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-18T17:58:39", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-18T20:40:22", + "duration": 1800000, + "extended": 5.7, + "normal": 1.9, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-19T08:36:08", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-19T15:20:39", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-19T18:22:28", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-19T18:54:15", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-19T22:20:06", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-19T22:47:22", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-20T14:23:03", + "duration": 3600000, + "extended": 1.35, + "normal": 5.4, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-20T15:02:15", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-20T15:50:21", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-21T00:08:35", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-21T12:12:24", + "normal": 5.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-21T15:13:53", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-22T16:11:14", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-23T01:06:51", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-23T10:37:02", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-23T16:18:09", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-23T16:57:31", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-23T21:30:01", + "duration": 1800000, + "extended": 3.55, + "normal": 1.15, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-24T08:03:19", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-24T13:21:49", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-24T13:41:26", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-24T15:13:42", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-24T17:30:34", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-24T18:47:01", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-25T00:37:32", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-25T15:27:34", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-25T15:50:46", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-25T18:34:45", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-26T08:00:02", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-26T15:30:21", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-26T16:43:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-26T22:55:06", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-27T00:34:23", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-27T16:08:38", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-28T10:22:34", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-28T10:42:12", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-28T11:14:05", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-28T12:22:02", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-28T17:58:24", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-29T00:59:10", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-29T13:21:48", + "normal": 3.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-29T14:26:37", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-29T15:29:23", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-29T19:11:00", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-29T21:59:18", + "duration": 10800000, + "extended": 8.65, + "normal": 2.85, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-30T07:29:04", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-30T11:32:41", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-30T13:33:42", + "normal": 2.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-30T15:10:57", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-30T16:48:04", + "duration": 2700000, + "expectedDuration": 3600000, + "expectedExtended": 2.65, + "extended": 1.95, + "normal": 4.5, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-30T17:35:25", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-31T06:01:14", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-31T08:02:24", + "expectedNormal": 1.8, + "normal": 0, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-31T17:32:27", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-31T19:24:54", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-31T20:15:14", + "normal": 7.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-31T23:11:02", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-01T15:38:03", + "normal": 7.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-02T00:53:24", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-02T09:42:56", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-02T12:33:40", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-03T13:13:56", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-03T13:30:33", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-03T19:02:46", + "normal": 7.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-03T23:23:36", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-03T23:30:48", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-04T07:57:10", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-04T17:05:51", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-04T18:14:03", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-05T16:45:27", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-05T19:47:08", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-06T09:25:42", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-06T15:20:44", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-06T16:19:31", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-06T17:07:49", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-06T19:58:23", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-07T14:38:43", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-07T19:47:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-07T20:51:30", + "normal": 8.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-07T21:31:38", + "normal": 5.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-08T01:05:38", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-08T10:11:09", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-08T15:43:17", + "normal": 6.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-08T19:52:56", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-08T20:57:40", + "duration": 3600000, + "extended": 2, + "normal": 8.95, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-09T09:07:47", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-09T16:17:45", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-09T17:24:45", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-11T01:12:55", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-11T18:24:34", + "normal": 5.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-11T19:04:48", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-11T20:30:46", + "normal": 0.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-12T10:04:06", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-13T17:30:51", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-13T18:15:01", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-13T18:43:29", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-14T15:37:44", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-15T01:47:54", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-15T13:59:56", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-15T14:41:43", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-15T14:44:38", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-15T21:54:18", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-16T15:51:57", + "normal": 7.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-16T16:23:22", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-16T20:59:44", + "normal": 7.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-16T22:28:09", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-17T13:43:39", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-17T15:22:58", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-17T20:43:00", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-17T22:37:07", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-18T12:51:55", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-18T15:37:39", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-18T16:20:47", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-18T16:23:34", + "expectedNormal": 1, + "normal": 0, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-18T16:23:47", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-19T01:18:52", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-19T18:35:04", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-19T18:45:16", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-19T19:19:18", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-19T19:49:49", + "normal": 9.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-20T13:23:57", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-20T18:56:03", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-21T18:29:04", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-21T20:46:21", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-22T21:10:05", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-22T21:58:04", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-22T22:02:55", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-23T18:27:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-23T20:31:41", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-23T20:59:54", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-23T23:21:11", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-24T10:24:29", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-24T17:07:32", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-24T17:33:08", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-24T18:35:51", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-25T14:07:13", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-25T17:12:17", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-25T21:24:58", + "normal": 8.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-26T11:35:34", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-26T11:48:12", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-26T12:08:19", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-26T16:13:11", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-26T22:12:41", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-27T01:27:13", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-27T16:56:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-27T19:56:41", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-27T20:22:28", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-27T20:57:07", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-28T07:42:06", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-28T09:05:30", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-28T09:54:05", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-28T14:01:25", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-28T15:50:43", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-28T20:59:49", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-28T21:29:58", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-29T01:28:07", + "expectedNormal": 3, + "normal": 0, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-29T01:28:23", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-29T05:09:40", + "expectedNormal": 2.55, + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-29T05:18:26", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-29T06:58:48", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-29T07:02:43", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-29T13:23:14", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-29T21:18:42", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-30T15:27:04", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-30T15:45:46", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-30T16:03:48", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-30T21:27:24", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-31T00:32:49", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-31T14:12:55", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-01T00:10:43", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-01T00:20:00", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-01T01:11:31", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-01T18:11:06", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-01T18:59:49", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-01T23:21:40", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T01:17:05", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T07:22:03", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T09:19:07", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T15:32:12", + "duration": 3600000, + "extended": 1.65, + "normal": 3.8, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T17:09:29", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T19:39:58", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T20:38:24", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T20:44:02", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T21:40:20", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-03T00:20:40", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-03T06:42:57", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-03T14:08:27", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-03T14:48:55", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-03T17:14:46", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-03T22:34:31", + "normal": 5.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-04T00:28:34", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-04T06:09:22", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-04T14:45:39", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-04T18:24:53", + "normal": 10.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-05T01:06:54", + "normal": 6.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-05T16:22:33", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-05T16:58:48", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-05T21:45:50", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-06T00:55:25", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-06T15:41:42", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-06T15:45:31", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-06T16:47:53", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-06T21:15:40", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-07T19:12:03", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-07T19:57:42", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-07T20:27:57", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-07T23:09:54", + "normal": 10.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-08T06:49:54", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-08T13:38:14", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-08T19:03:48", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-08T21:12:03", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-08T22:21:55", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-09T01:19:46", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-09T15:05:45", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-09T22:54:59", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-09T23:26:51", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-10T16:45:44", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-10T17:22:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-10T20:02:24", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-10T22:48:01", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-10T23:18:10", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-11T17:11:53", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-11T23:15:24", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-12T00:04:13", + "normal": 2.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-12T00:28:22", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-12T15:21:56", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-13T15:59:02", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-13T22:06:29", + "normal": 6.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-14T11:11:32", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-14T13:09:35", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-14T19:24:39", + "normal": 10.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-15T15:36:19", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-15T21:46:47", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-15T22:10:16", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-16T15:44:33", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-16T21:36:53", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-17T15:59:12", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-17T16:08:56", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-17T21:09:25", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-18T09:37:49", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-18T18:20:54", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-18T18:51:09", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-19T13:27:26", + "duration": 3600000, + "extended": 0.55, + "normal": 0.25, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-19T14:53:40", + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-19T15:24:30", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-20T18:32:41", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-20T21:29:36", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-21T15:35:49", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-21T21:03:52", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-21T22:39:49", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-22T11:25:56", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-22T13:19:40", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-22T17:25:35", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-22T19:59:31", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-22T22:50:19", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-23T11:45:40", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-23T11:47:49", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-23T12:07:32", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-23T15:08:45", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-23T20:33:01", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-23T22:00:40", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-24T06:08:59", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-24T08:33:59", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-24T11:22:33", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-24T21:52:26", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-24T22:08:46", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-25T16:52:46", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-25T20:23:33", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-25T20:36:44", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-26T07:18:20", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-26T10:15:04", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-26T16:11:43", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-26T19:25:09", + "normal": 6.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-26T21:22:26", + "normal": 1.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-27T12:14:07", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-27T13:57:02", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-27T14:09:20", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-27T15:29:54", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-27T20:48:41", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-27T21:12:09", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-27T21:20:49", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-27T21:49:25", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-28T04:50:11", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-28T07:40:45", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-28T12:06:19", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-28T15:46:19", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-28T21:47:01", + "normal": 12.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-29T01:12:35", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-29T02:08:17", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-29T02:59:26", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-29T14:42:33", + "normal": 7.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-29T15:02:43", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-29T15:12:10", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-29T19:10:18", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-29T19:46:49", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-30T11:29:40", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-30T13:56:15", + "normal": 5.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-30T15:42:59", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-30T22:53:22", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-30T23:05:22", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-30T23:35:16", + "normal": 7.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-01T14:27:43", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-01T16:04:42", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-01T22:28:45", + "normal": 6.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-02T17:01:12", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-02T18:18:32", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-02T22:08:17", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-02T22:56:37", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-03T07:44:00", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-03T08:42:58", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-03T15:24:28", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-03T17:53:59", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-03T19:00:37", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-03T22:17:33", + "normal": 7.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-04T09:52:11", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-04T12:55:58", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-04T15:12:11", + "normal": 6.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-04T20:09:22", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-05T03:27:19", + "normal": 4.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-05T19:22:47", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-05T22:39:45", + "normal": 10.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-06T06:12:37", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-06T12:42:06", + "normal": 8.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-06T15:32:00", + "expectedNormal": 4.7, + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-06T19:07:20", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-06T19:39:58", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-07T00:20:47", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-07T05:30:49", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-07T08:21:15", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-07T22:44:14", + "normal": 8.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-08T06:58:25", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-08T08:16:59", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-08T13:52:10", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-08T19:52:08", + "normal": 5.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-09T06:26:22", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-09T07:43:04", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-09T15:08:46", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-09T15:54:44", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-09T23:03:47", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-09T23:38:04", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-10T16:02:43", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-10T22:56:35", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-10T23:35:59", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-11T15:03:25", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-11T16:13:04", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-11T21:19:03", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-12T07:22:58", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-12T15:16:54", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-12T15:54:25", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-12T21:11:04", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-13T13:15:55", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-13T13:18:43", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-13T16:26:19", + "normal": 6.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-13T20:33:47", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-13T20:49:06", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-13T21:24:48", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-13T23:18:40", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-13T23:45:17", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-14T00:25:53", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-14T01:10:52", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-14T12:00:00", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-14T15:36:08", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-14T16:01:10", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-14T19:58:59", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-14T20:51:48", + "normal": 8.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-14T21:40:26", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-14T23:14:13", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-15T00:33:52", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-15T08:45:17", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-15T15:49:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-15T21:53:25", + "normal": 8.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-15T22:38:18", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-16T16:47:33", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-16T22:22:47", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-16T23:27:48", + "normal": 14.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-17T15:50:12", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-17T15:52:31", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-18T14:12:19", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-18T15:09:54", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-18T15:27:12", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-18T15:57:46", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-18T23:28:05", + "normal": 8.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-19T00:10:14", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-19T00:46:24", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-19T01:11:02", + "normal": 5.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-19T14:59:14", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-19T16:28:00", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-19T22:00:22", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-19T23:24:34", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-20T17:39:33", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-20T19:27:43", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-20T20:07:49", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-20T20:43:12", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-20T21:54:33", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-21T14:16:42", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-21T20:42:35", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-22T12:14:12", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-23T07:12:15", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-23T11:12:32", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-23T12:36:16", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-23T12:50:53", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-23T14:17:09", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-24T10:47:06", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-24T14:20:06", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-24T16:11:40", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-25T00:18:43", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-25T19:12:42", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-25T20:42:26", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-26T18:49:01", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-27T18:11:11", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-27T20:47:51", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-28T13:28:57", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-28T13:31:35", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-28T13:43:39", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-28T18:08:08", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-29T03:56:45", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-29T15:09:37", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-29T15:58:27", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-30T02:57:09", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-30T16:34:05", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-30T19:17:07", + "expectedNormal": 8, + "normal": 6.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-30T23:28:05", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-31T20:19:12", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-01T16:10:05", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-01T23:01:05", + "normal": 3.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-02T17:16:10", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-02T23:46:20", + "normal": 8.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-03T12:56:37", + "normal": 6.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-03T13:09:30", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-03T16:07:02", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-03T20:10:25", + "duration": 3600000, + "extended": 2.2, + "normal": 12.3, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-04T05:00:38", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-04T12:35:17", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-04T15:46:38", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-04T22:01:14", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-05T09:37:58", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-05T13:19:18", + "normal": 2, + "subType": "normal", + }, +} + +var PlatformBolusSet = []map[string]interface{}{ + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-11T05:48:32", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-11T05:48:32", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-11T08:48:43", + "normal": 2.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-11T08:48:43", + "normal": 2.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-11T17:07:35", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-11T17:48:17", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-11T22:16:32", + "expectedNormal": 6, + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T02:48:01", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T02:57:56", + "normal": 2.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T02:57:56", + "normal": 2.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T03:45:23", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T04:02:33", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T04:02:33", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T04:07:54", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T12:10:52", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T12:10:52", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T13:43:31", + "normal": 0.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T13:43:31", + "normal": 0.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T18:55:53", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-12T22:06:00", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-13T00:07:54", + "normal": 6.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-13T15:36:15", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-13T15:36:15", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-13T19:15:32", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-13T23:32:46", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-14T02:56:18", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-14T15:05:16", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-14T15:05:16", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-14T18:45:59", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-14T21:06:30", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-15T02:10:44", + "expectedNormal": 6, + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-15T10:11:52", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-15T10:21:08", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-15T10:52:13", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-15T18:51:32", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-15T20:32:07", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-15T20:43:33", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-15T20:43:33", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-15T21:26:55", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-16T07:56:57", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-16T07:56:57", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-16T15:32:09", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-16T15:32:09", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-16T16:04:19", + "expectedNormal": 3.7, + "normal": 0.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-16T16:04:45", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-16T16:23:41", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-16T16:35:34", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-16T16:58:46", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-16T22:04:48", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T07:49:22", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T07:49:22", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T07:58:22", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T08:31:44", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T09:25:59", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T15:19:35", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T15:41:16", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T16:13:32", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T16:51:39", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T17:36:34", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-17T22:24:30", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-18T00:26:16", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-18T00:57:05", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-18T09:39:10", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-18T13:26:16", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-18T15:56:31", + "normal": 0.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-18T15:56:31", + "normal": 0.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-18T16:46:24", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-18T17:16:59", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-18T17:16:59", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-19T01:21:09", + "normal": 2.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-19T01:21:09", + "normal": 2.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-19T01:51:44", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-19T18:01:16", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-19T19:01:35", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-19T22:24:42", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-19T22:27:54", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-19T23:16:39", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-20T11:50:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-20T13:36:40", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-20T13:36:40", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-20T18:31:12", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-20T19:04:49", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-20T19:13:53", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-21T14:16:39", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-22T00:12:03", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-22T00:12:03", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-22T13:54:39", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-22T20:02:33", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-22T20:09:02", + "normal": 7.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-22T20:42:46", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-22T20:51:20", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-23T14:51:38", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-23T14:51:38", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-23T17:40:56", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-24T10:57:40", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-24T13:49:15", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-24T13:49:15", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-24T20:29:08", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-24T20:29:08", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-24T23:20:14", + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-24T23:20:14", + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T02:11:25", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T02:11:25", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T03:41:15", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T03:49:26", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T11:34:54", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T11:36:30", + "expectedNormal": 3.7, + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T11:39:54", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T18:55:44", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T21:00:32", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T21:56:23", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-25T22:40:16", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-26T00:47:19", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-26T11:19:24", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-26T11:19:24", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-26T18:22:46", + "normal": 9.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-26T18:22:46", + "normal": 9.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-26T20:06:31", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-26T21:00:39", + "normal": 4.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-27T00:43:11", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-27T00:54:23", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-27T01:21:34", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-27T01:21:34", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-27T07:02:47", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-27T08:20:19", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-27T08:20:19", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-27T11:57:25", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-27T18:36:04", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-27T20:18:11", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-28T10:55:51", + "normal": 10.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-28T13:31:27", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-28T17:47:15", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-28T18:58:25", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-28T20:20:09", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T05:47:36", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T11:04:51", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T11:17:10", + "expectedNormal": 5, + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T11:17:44", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T11:59:21", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T11:59:21", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T12:33:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T16:04:51", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T18:22:02", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T18:22:02", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-29T20:35:15", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-30T00:19:10", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-30T01:14:53", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-30T11:38:04", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-30T11:38:04", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-30T14:10:30", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-30T18:11:40", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-30T19:40:37", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-11-30T22:39:58", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-01T09:55:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-01T12:02:23", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-01T12:02:23", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-01T12:11:07", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-01T15:03:11", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-01T23:36:08", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-02T13:42:27", + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-02T13:42:27", + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-03T08:36:32", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-03T12:46:16", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-03T14:31:00", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-03T19:01:03", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-03T19:13:12", + "duration": 3600000, + "extended": 1.35, + "normal": 3.25, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-03T19:13:12", + "duration": 3600000, + "extended": 1.35, + "normal": 3.25, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-03T23:09:17", + "expectedNormal": 5.6, + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-03T23:09:17", + "expectedNormal": 5.6, + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-04T01:32:34", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-04T13:31:48", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-04T23:45:20", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-05T05:38:22", + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-05T05:38:22", + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-05T13:05:36", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-05T18:04:44", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-05T22:31:49", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-06T09:05:49", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-06T19:44:34", + "normal": 3.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-06T19:44:34", + "normal": 3.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-07T11:30:47", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-07T17:39:58", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-08T09:36:46", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-08T09:36:46", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-08T12:09:06", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-08T13:51:33", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-08T13:51:33", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-08T22:47:22", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-08T23:06:37", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-08T23:34:05", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-09T11:51:03", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-09T18:28:48", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-09T18:41:43", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-09T19:46:42", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-09T19:46:42", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-09T22:41:34", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-10T03:05:28", + "normal": 1.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-10T03:05:28", + "normal": 1.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-10T11:34:38", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-10T14:55:50", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-10T15:23:08", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-10T19:28:56", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-10T21:16:11", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-10T22:17:25", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-11T14:30:42", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-11T19:17:18", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-12T13:15:43", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-12T14:37:19", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-12T20:45:23", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-12T21:17:50", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-12T22:07:50", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-12T23:57:33", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-12T23:57:33", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-13T10:28:04", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-13T10:28:04", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-13T17:42:12", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-14T04:31:16", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-14T09:40:01", + "normal": 3.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-14T09:40:01", + "normal": 3.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-14T15:57:40", + "normal": 2.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-14T15:57:40", + "normal": 2.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-14T17:26:58", + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-14T17:26:58", + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-15T05:49:43", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-15T09:42:54", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-15T09:42:54", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-15T15:42:11", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-15T17:58:05", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-15T20:36:40", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-15T21:54:57", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-16T02:10:54", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-16T05:18:35", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-16T05:18:35", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-16T17:03:43", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-16T21:17:40", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-16T21:27:12", + "expectedNormal": 1.8, + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-17T15:02:37", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-17T15:02:37", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-18T08:53:51", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-18T08:53:51", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-18T14:07:21", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-18T14:07:21", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-19T00:37:12", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-20T22:52:22", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-20T22:52:22", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-21T16:04:44", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-21T16:04:44", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-21T17:31:36", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-22T20:34:13", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T00:32:29", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T00:32:29", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T02:01:53", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T02:01:53", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T13:25:12", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T14:45:29", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T14:45:29", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T15:17:41", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T15:27:27", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T20:51:42", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T20:51:42", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T22:28:05", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-23T22:28:05", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-24T15:45:49", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-24T15:45:49", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-24T17:30:54", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-25T03:24:31", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-25T17:51:24", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-25T18:17:02", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-25T18:44:42", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-25T19:06:09", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-26T04:38:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-26T21:52:20", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-26T22:10:35", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-27T00:35:55", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-27T12:09:08", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-27T13:12:31", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-27T22:06:04", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-27T23:57:59", + "normal": 8.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-27T23:57:59", + "normal": 8.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-28T13:41:05", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-28T13:41:05", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-28T21:53:48", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-28T21:53:48", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-28T22:38:58", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-28T23:35:34", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-29T01:10:10", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-29T13:28:49", + "normal": 7.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-29T15:31:09", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-29T15:47:25", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-29T20:49:26", + "normal": 10.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-29T20:49:26", + "normal": 10.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-29T23:31:22", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T01:14:51", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T01:14:51", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T10:07:54", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T14:41:41", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T14:41:41", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T15:36:28", + "normal": 0.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T15:36:28", + "normal": 0.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T17:21:07", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T17:47:07", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T17:47:07", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T19:43:22", + "normal": 10.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T21:42:19", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T23:34:45", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-30T23:57:13", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-31T14:15:24", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-31T15:37:20", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-31T16:37:23", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-31T20:22:35", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2017-12-31T22:50:28", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-01T00:18:37", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-01T03:28:56", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-01T08:23:20", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-01T17:09:58", + "normal": 5.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-01T17:09:58", + "normal": 5.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-01T20:29:55", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-01T21:39:29", + "normal": 11.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-01T21:39:29", + "normal": 11.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T01:37:45", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T01:37:45", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T09:05:27", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T09:05:27", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T09:28:02", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T09:28:02", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T15:17:44", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T15:17:44", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T17:05:07", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T21:57:29", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T21:57:29", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T22:31:41", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T23:58:14", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-02T23:58:14", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-03T06:23:16", + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-03T06:23:16", + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-03T13:07:10", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-03T13:07:10", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-03T17:36:24", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-03T17:36:24", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-03T19:19:53", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-04T20:39:32", + "normal": 12.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-04T23:27:30", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-05T11:26:40", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-05T14:39:47", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-05T21:24:08", + "normal": 12.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-05T23:47:57", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-06T10:29:13", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-07T02:43:11", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-07T15:29:23", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-07T15:53:38", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-08T00:50:58", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-08T02:22:40", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-08T10:49:22", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-08T12:10:15", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-08T16:06:15", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-08T21:00:55", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-08T22:52:11", + "normal": 13.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-09T06:48:05", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-09T11:57:20", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-09T14:50:09", + "expectedNormal": 7.1, + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-09T15:09:57", + "expectedNormal": 5.3, + "normal": 0, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-09T15:10:07", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-09T15:45:24", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-09T19:08:06", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-10T00:20:48", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-10T09:57:07", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-10T15:19:38", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-10T15:19:38", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-10T19:51:35", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-10T21:04:03", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-11T17:21:27", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-11T23:50:01", + "normal": 9.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-11T23:50:01", + "normal": 9.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-12T14:21:27", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-13T01:22:50", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-13T09:16:42", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-13T09:45:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-13T17:59:12", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-13T19:51:42", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-14T01:09:36", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-14T01:09:36", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-14T15:27:34", + "normal": 6.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-14T15:37:30", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-14T19:52:15", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-14T22:44:38", + "normal": 11, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-14T23:04:59", + "expectedNormal": 8.7, + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-15T08:08:01", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-15T08:08:01", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-15T17:50:26", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-15T18:22:34", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-15T22:12:43", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-16T05:28:57", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-16T19:06:03", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-18T00:44:27", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-18T00:44:27", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-18T15:16:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-18T21:34:19", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-19T15:18:48", + "normal": 7.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-19T15:18:48", + "normal": 7.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-19T18:24:25", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-19T21:40:18", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-20T01:57:09", + "normal": 5.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-20T01:57:09", + "normal": 5.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-20T05:21:15", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-20T14:43:26", + "normal": 2.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-20T14:43:26", + "normal": 2.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-20T20:23:29", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-20T23:15:21", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-21T01:47:25", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-21T01:47:25", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-21T16:32:58", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-21T16:32:58", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-21T21:12:41", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-22T13:07:23", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-22T13:24:37", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-22T13:38:43", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-22T13:38:43", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-22T14:23:46", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-23T00:01:17", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-23T02:53:10", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-23T10:26:09", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-23T12:45:53", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-23T19:04:33", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-24T02:03:30", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-24T02:03:30", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-24T08:42:05", + "normal": 3.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-24T08:42:05", + "normal": 3.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-24T09:11:28", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-24T13:05:25", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-24T16:20:41", + "normal": 0.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-24T16:20:41", + "normal": 0.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-24T19:39:24", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-24T22:58:57", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-24T22:58:57", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-25T09:05:32", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-25T09:15:49", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-25T10:05:32", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-25T15:20:46", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-26T00:34:00", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-26T00:40:32", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-26T17:42:21", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-27T00:26:46", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-27T01:56:53", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-27T15:00:57", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-27T16:30:36", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-28T00:07:24", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-28T04:04:35", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-28T11:06:58", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-28T12:05:56", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-28T17:32:14", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-28T22:51:31", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-29T09:24:11", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-29T11:48:49", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-01-31T17:35:53", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-01T22:39:45", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-01T23:11:22", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-02T05:32:22", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-02T13:53:59", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-02T15:01:02", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-03T11:47:19", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-03T17:52:13", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-04T00:51:30", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-04T01:35:03", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-04T10:23:28", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-05T00:40:31", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-05T22:10:18", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-06T00:30:31", + "duration": 9000000, + "extended": 2.4, + "normal": 0.1, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-06T00:30:31", + "duration": 9000000, + "extended": 2.4, + "normal": 0.1, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-06T11:27:46", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-06T12:24:47", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-06T12:24:47", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-06T21:00:06", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-06T21:26:09", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-06T22:30:08", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-07T01:20:24", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-07T01:20:24", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-07T15:08:42", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-07T17:35:21", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-07T17:35:21", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-08T00:40:52", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-08T00:40:52", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-08T04:05:56", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-08T04:08:07", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-08T20:24:34", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-08T21:17:19", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-09T03:41:21", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-09T03:43:00", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-09T15:27:27", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-09T15:27:27", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-09T16:50:23", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-10T00:06:05", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-10T07:13:02", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-10T10:23:08", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-11T01:16:30", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-11T13:20:10", + "normal": 1.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-11T13:20:10", + "normal": 1.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-11T17:04:18", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-11T19:38:24", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-11T20:40:19", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-11T22:22:57", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-11T23:03:25", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-12T10:31:15", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-12T10:47:00", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-12T17:15:24", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-12T22:52:54", + "duration": 5400000, + "extended": 3.6, + "normal": 0.4, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-12T22:52:54", + "duration": 5400000, + "extended": 3.6, + "normal": 0.4, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-12T23:37:16", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-13T03:06:20", + "expectedNormal": 2.4, + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-13T04:51:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-13T19:40:33", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-13T20:05:03", + "normal": 0.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-14T17:20:11", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-14T17:56:34", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-15T01:56:38", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-15T17:29:22", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-16T09:23:19", + "normal": 2.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-16T09:23:19", + "normal": 2.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-17T11:56:27", + "normal": 0.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-17T11:56:27", + "normal": 0.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-18T00:34:51", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-18T04:32:23", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-18T12:15:36", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-18T12:56:37", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-18T20:43:52", + "normal": 9.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-19T03:06:10", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-19T17:37:52", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-19T17:37:52", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-19T18:33:24", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-19T22:24:06", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-19T23:15:16", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-19T23:57:50", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-20T11:27:44", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-20T12:13:32", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-20T17:12:58", + "normal": 7.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-20T17:12:58", + "normal": 7.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-20T23:25:38", + "normal": 4.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-20T23:25:38", + "normal": 4.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-21T18:12:48", + "normal": 4.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-21T23:02:43", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-22T05:11:08", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-22T12:46:46", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-22T18:44:55", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-22T23:47:30", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-23T15:22:30", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-24T01:28:13", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-24T04:50:59", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-24T04:50:59", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-24T10:06:16", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-24T10:57:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-24T16:20:38", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-24T20:57:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-24T21:10:06", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-25T01:46:05", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-25T03:01:41", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-25T03:01:41", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-25T12:45:34", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-25T16:35:50", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-25T16:43:09", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-26T14:50:38", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-26T23:18:20", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-27T19:10:37", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-27T19:56:05", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-27T20:05:22", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-02-27T20:33:26", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-01T11:06:45", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-01T13:38:00", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-01T13:38:00", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-01T17:26:06", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-02T05:10:59", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-02T14:53:50", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-02T15:15:41", + "duration": 7200000, + "extended": 4, + "normal": 2.65, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-02T15:15:41", + "duration": 7200000, + "extended": 4, + "normal": 2.65, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-02T17:55:24", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-02T21:27:07", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-02T21:27:07", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-03T02:23:28", + "normal": 3.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-03T02:23:28", + "normal": 3.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-03T07:55:24", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-03T13:31:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-03T17:33:40", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-04T01:00:34", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-04T09:51:54", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-04T13:59:53", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-04T14:53:15", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-04T17:26:51", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-04T19:38:13", + "normal": 8.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-04T23:09:52", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-04T23:57:26", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-04T23:57:26", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-05T03:09:50", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-05T14:54:46", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-05T18:29:31", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-06T00:34:35", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-06T01:21:36", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-06T06:12:45", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-06T19:38:19", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-07T08:26:18", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-07T10:24:27", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-07T16:59:43", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-07T22:10:21", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-07T23:47:40", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-08T00:47:32", + "duration": 10800000, + "extended": 1.65, + "subType": "square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-08T00:47:32", + "duration": 10800000, + "extended": 1.65, + "subType": "square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-08T17:20:24", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-08T23:16:45", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-08T23:16:45", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-09T09:43:12", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-09T19:36:18", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-09T21:47:07", + "normal": 11, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-09T22:28:29", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-10T00:56:27", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-10T05:18:33", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-10T10:09:03", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-10T19:08:41", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-10T19:30:42", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-10T21:00:08", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-10T21:11:26", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-11T00:12:25", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-11T00:12:25", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-11T03:50:32", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-11T09:48:55", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-11T17:56:25", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-11T21:45:42", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-11T23:48:21", + "normal": 7.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-11T23:59:24", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-12T11:02:19", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-12T14:13:44", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-12T23:30:03", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-13T00:01:21", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-13T08:23:02", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-13T15:29:58", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-13T16:25:10", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-14T01:00:14", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-14T01:48:33", + "duration": 7200000, + "extended": 5, + "subType": "square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-14T08:26:33", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-14T09:15:40", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-14T21:17:36", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-14T21:36:42", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-15T01:00:44", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-15T12:10:00", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-15T13:36:53", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-15T21:24:43", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-15T22:46:02", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-16T19:49:33", + "normal": 12.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-16T19:49:33", + "normal": 12.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-17T15:56:01", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-17T15:56:01", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-18T10:02:04", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-18T15:29:15", + "normal": 6.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-18T15:29:15", + "normal": 6.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-18T16:27:25", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-18T21:15:02", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-19T06:28:44", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-19T15:28:25", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-19T22:15:08", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-20T08:14:49", + "duration": 3600000, + "extended": 1.5, + "normal": 0.5, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-20T12:02:19", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-20T13:19:06", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-20T16:07:19", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-20T19:43:27", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-20T20:56:53", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-21T00:32:48", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-21T14:39:05", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-21T21:09:21", + "normal": 12, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-21T22:14:04", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-22T03:19:52", + "expectedNormal": 5.15, + "normal": 0.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-22T03:19:52", + "expectedNormal": 5.15, + "normal": 0.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-22T03:20:35", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-22T10:57:48", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-22T16:15:49", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-22T23:32:14", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-23T03:44:48", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-23T10:03:49", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-23T12:03:21", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-23T12:03:21", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-23T12:08:31", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-23T17:28:19", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-23T18:10:06", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-23T22:45:10", + "normal": 6.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-23T23:57:11", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-24T01:52:51", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-24T04:04:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-24T10:09:10", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-24T15:22:15", + "normal": 9.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-24T15:59:21", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-24T18:45:12", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-25T03:44:15", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-25T04:12:56", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-25T13:25:50", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-25T15:47:08", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-25T16:27:53", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-25T16:27:53", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-25T17:26:51", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-26T01:03:51", + "normal": 9.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-26T01:03:51", + "normal": 9.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-26T04:48:39", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-26T15:52:08", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-26T18:11:28", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-26T21:42:00", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-26T23:21:43", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-27T13:11:38", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-27T13:27:58", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-27T13:43:12", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-27T14:19:41", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-28T01:21:26", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-28T02:49:55", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-28T02:49:55", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-28T12:09:39", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-28T21:12:56", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-29T01:42:57", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-29T12:10:07", + "normal": 8.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-29T12:10:07", + "normal": 8.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-29T20:29:43", + "normal": 8.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-29T20:29:43", + "normal": 8.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-29T23:08:20", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-29T23:23:56", + "expectedNormal": 2, + "normal": 0.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-29T23:24:13", + "expectedNormal": 3.8, + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-29T23:25:03", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-30T09:17:33", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-30T11:41:40", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-30T18:46:16", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-30T22:26:35", + "normal": 7.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-30T22:26:35", + "normal": 7.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-31T09:34:04", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-31T11:02:09", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-03-31T18:03:31", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-01T13:35:12", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-01T19:00:43", + "expectedNormal": 5.5, + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-02T11:24:01", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-02T11:24:01", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-03T00:24:02", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-03T00:24:02", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-03T04:46:03", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-03T13:58:14", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-03T15:41:52", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-03T22:48:16", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-03T22:48:16", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-03T22:53:19", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-03T23:37:06", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-04T17:49:44", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-04T18:25:58", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-04T20:06:51", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-04T20:50:31", + "expectedNormal": 6.5, + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-04T21:47:42", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-05T11:10:22", + "normal": 8.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-05T13:57:52", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-05T14:41:02", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-05T19:55:35", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-05T20:07:23", + "normal": 6.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-05T20:07:23", + "normal": 6.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-05T23:10:52", + "normal": 10.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-05T23:10:52", + "normal": 10.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-06T17:04:13", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-07T00:30:35", + "normal": 13, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-07T11:30:23", + "expectedNormal": 11.3, + "normal": 7.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-07T11:30:23", + "expectedNormal": 11.3, + "normal": 7.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-07T13:39:36", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-07T15:31:20", + "normal": 7.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-07T17:03:27", + "normal": 6.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-07T19:36:38", + "normal": 11.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-07T19:36:38", + "normal": 11.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T02:04:38", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T02:04:38", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T11:36:22", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T11:36:22", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T15:35:43", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T16:36:54", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T17:06:19", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T17:06:19", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T18:36:43", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T20:45:53", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T21:43:56", + "normal": 5.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T22:27:26", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-08T22:27:26", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-09T13:34:32", + "normal": 4.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-09T13:34:32", + "normal": 4.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-09T23:51:42", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-10T11:33:52", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-10T15:06:31", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-10T16:39:01", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-10T23:28:10", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-10T23:28:10", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-10T23:56:06", + "normal": 3.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-10T23:56:06", + "normal": 3.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-11T08:31:34", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-11T14:14:04", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-11T21:33:10", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-11T21:33:10", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-12T13:11:06", + "normal": 5.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-12T15:22:32", + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-12T15:22:32", + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-12T20:37:48", + "duration": 3600000, + "extended": 1.4, + "normal": 4.1, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-12T20:37:48", + "duration": 3600000, + "extended": 1.4, + "normal": 4.1, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-13T07:00:52", + "normal": 2.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-13T07:00:52", + "normal": 2.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-13T11:55:34", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-13T15:38:33", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-13T15:38:33", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-13T16:43:21", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-13T22:25:40", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-13T23:43:31", + "duration": 3600000, + "extended": 3, + "normal": 4.5, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-13T23:43:31", + "duration": 3600000, + "extended": 3, + "normal": 4.5, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-14T07:24:30", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-14T11:26:07", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-14T14:02:33", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-14T16:13:29", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-14T16:21:37", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-15T04:30:42", + "normal": 2.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-15T04:30:42", + "normal": 2.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-15T11:27:28", + "normal": 9.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-15T21:09:40", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-15T21:29:47", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-16T08:42:28", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-16T08:42:28", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-16T09:08:02", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-16T18:50:11", + "normal": 7.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-16T18:50:11", + "normal": 7.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-16T22:19:29", + "normal": 8.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-16T22:19:29", + "normal": 8.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-17T07:49:58", + "expectedNormal": 6.25, + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-17T07:49:58", + "expectedNormal": 6.25, + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-17T10:22:10", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-17T15:38:57", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-17T16:53:15", + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-17T16:53:15", + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-17T23:01:44", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-17T23:01:44", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-17T23:17:46", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-18T03:36:54", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-18T08:15:40", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-18T13:03:08", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-18T13:03:08", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-18T22:49:11", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-19T10:49:57", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-19T10:49:57", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-19T12:47:07", + "normal": 7.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-19T12:47:07", + "normal": 7.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-19T18:51:49", + "normal": 0.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-19T18:51:49", + "normal": 0.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T00:34:12", + "normal": 4.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T00:34:12", + "normal": 4.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T11:55:56", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T11:55:56", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T12:21:25", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T12:25:59", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T12:40:44", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T16:51:52", + "normal": 5.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T16:51:52", + "normal": 5.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T17:13:53", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T18:53:57", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T21:13:02", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T21:17:28", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-20T22:56:20", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-21T05:00:30", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-21T05:00:30", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-21T14:57:12", + "expectedNormal": 5.7, + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-21T17:25:57", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-21T19:55:14", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-21T20:21:02", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-21T20:48:12", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-21T23:36:01", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-22T00:17:02", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-22T07:20:00", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-22T07:20:00", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-22T09:32:51", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-22T15:34:54", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-22T17:17:07", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-22T18:33:33", + "normal": 8.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-22T19:56:36", + "normal": 4.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-22T21:38:22", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-23T14:44:27", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-23T16:39:55", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-23T17:17:36", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-23T18:45:04", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-23T21:54:57", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-23T23:08:34", + "expectedNormal": 2.5, + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-23T23:30:54", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-24T10:55:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-24T16:10:07", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-24T16:10:07", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-24T18:45:06", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-24T18:45:06", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-24T21:29:29", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-25T02:05:38", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-25T16:31:35", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-25T16:52:59", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-25T23:23:29", + "normal": 9.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-25T23:23:29", + "normal": 9.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-26T10:15:03", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-26T13:15:18", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-26T13:53:04", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-26T15:43:54", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-26T20:06:36", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-27T12:42:46", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-27T15:48:19", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-27T15:53:18", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-27T23:14:39", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-28T02:49:38", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-28T14:15:39", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-28T14:15:39", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-28T15:36:19", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-28T17:22:40", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-28T23:33:46", + "normal": 6.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-29T12:43:56", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-29T14:24:57", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-29T16:00:35", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-29T16:00:35", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-29T22:51:00", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-30T16:41:59", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-30T23:51:20", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-04-30T23:51:20", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-01T00:40:06", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-01T02:19:29", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-01T15:47:28", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-01T17:58:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-01T17:58:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-02T01:01:32", + "duration": 5400000, + "extended": 1.85, + "normal": 0.05, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-02T01:01:32", + "duration": 5400000, + "extended": 1.85, + "normal": 0.05, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-02T14:35:54", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-02T16:30:55", + "normal": 1.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-02T16:30:55", + "normal": 1.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-02T18:03:13", + "normal": 2.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-02T18:03:13", + "normal": 2.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-02T18:30:32", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-02T22:44:03", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-03T13:28:40", + "normal": 7.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-03T13:28:40", + "normal": 7.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-03T22:38:40", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-03T22:38:40", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-04T06:40:11", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-04T12:09:02", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-04T12:42:38", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-04T13:58:04", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-04T19:31:20", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-04T19:31:20", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-05T13:12:58", + "normal": 5.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-05T13:12:58", + "normal": 5.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-05T17:02:00", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-05T17:02:00", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-05T22:18:24", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-05T22:18:24", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-06T12:34:16", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-06T20:28:21", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-06T21:05:28", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-07T10:11:40", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-07T12:47:09", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-07T12:47:09", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-07T20:59:51", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-07T21:46:06", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-08T07:29:03", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-08T07:29:03", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-08T13:44:00", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-08T13:44:00", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-08T20:00:38", + "normal": 2.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-08T20:00:38", + "normal": 2.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-09T14:28:06", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-09T14:28:06", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-09T23:50:14", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-10T10:13:12", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-10T12:28:54", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-10T12:28:54", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-10T14:38:18", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-10T18:48:40", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-10T18:48:40", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-10T19:22:11", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-10T20:10:02", + "normal": 0.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-10T20:10:02", + "normal": 0.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-10T20:43:41", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-11T02:11:06", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-11T15:22:52", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-11T19:51:32", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-11T20:01:17", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-11T21:07:27", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-11T22:40:53", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-12T00:51:28", + "normal": 5.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-12T00:51:28", + "normal": 5.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-12T09:31:50", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-12T17:24:32", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-12T17:31:58", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-12T19:20:54", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-12T20:09:19", + "normal": 6.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-12T23:53:39", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-13T06:04:08", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-13T09:33:30", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-13T09:33:30", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-13T10:02:35", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-13T13:25:22", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-13T14:39:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-13T21:27:31", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-13T21:49:54", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-13T21:49:54", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-14T06:30:45", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-14T17:13:50", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-14T17:13:50", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-14T19:51:30", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-15T02:59:12", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-15T18:34:17", + "normal": 8.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-15T18:34:17", + "normal": 8.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-15T20:03:48", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-15T20:13:10", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-15T21:08:56", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-15T21:38:31", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-16T11:44:10", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-16T13:54:41", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-16T17:33:07", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-16T18:59:52", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-16T22:40:06", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-16T22:40:06", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-17T10:47:43", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-17T17:33:07", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-17T17:33:07", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-17T21:09:30", + "normal": 8.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-17T21:09:30", + "normal": 8.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-17T21:38:23", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-17T21:38:23", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-18T14:40:29", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-18T16:20:15", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-18T17:18:29", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-18T21:04:49", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-18T21:04:49", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-19T08:29:53", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-19T08:29:53", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-19T10:55:07", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-19T13:03:51", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-19T20:15:44", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-19T20:28:37", + "normal": 10.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-19T20:28:37", + "normal": 10.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-20T00:18:39", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-20T01:24:17", + "normal": 0.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-20T01:24:17", + "normal": 0.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-20T07:49:45", + "normal": 0.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-20T07:49:45", + "normal": 0.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-20T11:51:55", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-20T12:13:22", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-20T14:57:44", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-20T18:03:00", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-21T10:31:41", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-21T10:31:41", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-21T13:57:19", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-21T19:23:59", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-21T19:23:59", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-21T22:46:23", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-22T09:51:09", + "normal": 9.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-22T09:51:09", + "normal": 9.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-22T19:41:23", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-22T19:41:23", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-22T22:49:19", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-23T07:43:22", + "normal": 5.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-23T07:43:22", + "normal": 5.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-23T15:05:51", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-23T15:05:51", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-23T16:43:30", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-23T16:43:30", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-23T20:24:21", + "normal": 10.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-23T20:24:21", + "normal": 10.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-23T20:36:41", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-24T01:31:04", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-24T01:31:04", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-24T12:17:15", + "normal": 4.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-24T12:17:15", + "normal": 4.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-24T13:52:54", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-24T22:00:26", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-24T22:31:42", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-24T22:31:42", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-25T07:08:36", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-25T07:08:36", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-25T09:25:26", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-25T09:25:26", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-25T10:43:07", + "duration": 3600000, + "extended": 2.15, + "normal": 6.35, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-25T10:43:07", + "duration": 3600000, + "extended": 2.15, + "normal": 6.35, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-25T15:29:54", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-25T19:28:58", + "normal": 4.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-25T21:48:56", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-26T07:47:05", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-26T15:09:57", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-26T15:23:19", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-26T19:21:32", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-26T19:21:32", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-26T22:54:32", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-27T08:07:50", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-27T08:07:50", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-27T12:47:09", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-27T12:47:09", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-27T13:23:20", + "normal": 1.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-27T13:23:20", + "normal": 1.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-27T17:55:40", + "normal": 7.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-27T19:30:40", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-27T22:57:00", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-28T02:25:19", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-28T16:54:27", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-28T16:54:27", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-28T17:18:04", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-28T19:15:15", + "normal": 6.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-28T20:51:16", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-28T23:10:50", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-29T01:18:06", + "normal": 1.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-29T01:18:06", + "normal": 1.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-29T14:47:42", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-29T16:34:10", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-29T22:26:32", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-31T04:03:49", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-31T10:56:21", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-31T13:27:12", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-31T19:41:58", + "normal": 2.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-31T19:41:58", + "normal": 2.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-31T21:08:12", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-31T21:08:12", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-31T22:40:45", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-05-31T23:11:40", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-01T11:33:30", + "normal": 2.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-01T11:33:30", + "normal": 2.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-01T20:49:42", + "normal": 5.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-01T20:49:42", + "normal": 5.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-01T23:31:41", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-02T02:42:26", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-02T02:42:26", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-02T03:08:32", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-02T12:36:04", + "normal": 7.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-02T12:36:04", + "normal": 7.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-02T13:23:44", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-02T20:07:26", + "normal": 7.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-03T15:01:33", + "normal": 0.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-03T15:46:39", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-03T16:41:33", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-03T17:18:38", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-03T17:43:38", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-04T10:16:53", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-04T14:50:00", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-04T16:14:19", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-04T19:21:41", + "normal": 8.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-04T19:21:41", + "normal": 8.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-04T23:46:41", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-05T00:44:34", + "expectedNormal": 2, + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-05T01:02:58", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-05T12:01:09", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-05T12:01:09", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-05T12:23:18", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-05T12:51:54", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-05T15:39:48", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-05T15:39:48", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-05T21:29:36", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-05T21:29:36", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-06T04:21:34", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-06T04:21:34", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-06T08:53:58", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-06T08:53:58", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-07T15:08:48", + "normal": 0.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-10T19:54:26", + "normal": 7.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-08T15:53:04", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-08T15:53:04", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-08T22:22:31", + "normal": 7.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-08T22:47:20", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-09T15:51:36", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-10T00:59:27", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-10T00:59:27", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-10T10:23:36", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-10T18:30:44", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-10T18:39:41", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-10T18:39:41", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-10T19:47:34", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-11T13:53:18", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-11T20:58:05", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-12T00:35:54", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-12T13:04:51", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-12T17:37:35", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-12T19:09:48", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-12T19:09:48", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-12T19:34:40", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-13T00:02:43", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-13T00:11:41", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-13T00:11:41", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-13T08:33:39", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-13T20:19:52", + "duration": 1800000, + "extended": 2.55, + "normal": 0.6, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-13T20:19:52", + "duration": 1800000, + "extended": 2.55, + "normal": 0.6, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-14T16:44:31", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-14T16:44:31", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-14T22:46:55", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-15T00:28:57", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-15T08:51:33", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-15T11:33:53", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-15T19:09:51", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-16T17:02:11", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-16T17:02:11", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-16T18:49:50", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-16T20:22:02", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-17T11:14:04", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-17T19:29:27", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-18T06:45:25", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-18T15:28:35", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-18T16:20:17", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-18T16:50:44", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-18T22:16:57", + "duration": 3600000, + "extended": 4.2, + "normal": 2.8, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-18T22:16:57", + "duration": 3600000, + "extended": 4.2, + "normal": 2.8, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-19T07:18:23", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-19T18:51:48", + "normal": 4.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-19T18:51:48", + "normal": 4.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-20T08:50:29", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-20T11:19:38", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-20T11:19:38", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-20T15:42:53", + "duration": 1800000, + "extended": 0.45, + "normal": 1.3, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-20T15:42:53", + "duration": 1800000, + "extended": 0.45, + "normal": 1.3, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-20T17:25:24", + "duration": 3600000, + "extended": 0.75, + "normal": 3, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-20T17:25:24", + "duration": 3600000, + "extended": 0.75, + "normal": 3, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-20T21:38:30", + "duration": 3600000, + "extended": 2.85, + "normal": 6.55, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-20T21:38:30", + "duration": 3600000, + "extended": 2.85, + "normal": 6.55, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-21T11:54:08", + "duration": 3600000, + "extended": 2.8, + "normal": 2.8, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-21T14:39:04", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-21T14:39:04", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-21T18:23:31", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-21T19:29:16", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-21T20:00:12", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-21T20:00:12", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-21T21:40:40", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-21T23:42:55", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-22T00:24:30", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-22T08:20:59", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-22T08:20:59", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-22T21:37:44", + "duration": 3600000, + "extended": 1.2, + "normal": 4.8, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-22T21:37:44", + "duration": 3600000, + "extended": 1.2, + "normal": 4.8, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-22T22:25:47", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-22T23:37:05", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-22T23:37:05", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-23T07:32:39", + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-23T07:32:39", + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-23T19:09:07", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-23T20:27:18", + "duration": 3600000, + "extended": 1.75, + "normal": 3.25, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-23T22:28:35", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-23T23:23:04", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T08:19:28", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T08:19:28", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T09:04:06", + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T09:04:06", + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T10:00:56", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T10:00:56", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T18:30:46", + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T18:30:46", + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T19:44:10", + "normal": 1.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T19:44:10", + "normal": 1.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T20:32:30", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T20:39:38", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-24T20:39:38", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-25T09:17:23", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-25T16:59:11", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-25T16:59:11", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-25T17:49:12", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-25T19:55:43", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-25T19:55:43", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-26T03:01:17", + "normal": 1.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-26T03:01:17", + "normal": 1.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-26T07:05:35", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-26T09:44:50", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-26T09:44:50", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-27T16:48:06", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-27T17:13:45", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-27T17:57:18", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-27T22:06:32", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-27T22:06:32", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-28T15:46:44", + "normal": 6.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-28T15:46:44", + "normal": 6.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-28T16:18:13", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-28T16:23:18", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-28T16:28:41", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-29T18:27:23", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-29T18:27:23", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-30T12:43:51", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-06-30T12:43:51", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-01T17:46:55", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-01T17:46:55", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-01T18:30:32", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-01T18:51:38", + "normal": 4.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-01T18:51:38", + "normal": 4.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-02T00:15:19", + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-02T00:15:19", + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-02T06:49:58", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-02T06:49:58", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-02T18:35:00", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-02T18:35:00", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-03T12:03:51", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-03T12:50:24", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-03T17:08:12", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-03T17:41:00", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-03T17:41:00", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-03T19:08:04", + "expectedNormal": 2, + "normal": 0.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-03T19:08:18", + "normal": 0.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-04T01:21:22", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-04T14:10:31", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-04T14:10:31", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-04T17:59:30", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-04T17:59:30", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-04T19:21:37", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-04T19:21:37", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-04T19:25:51", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-04T20:09:01", + "normal": 7.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-04T20:09:01", + "normal": 7.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-05T02:02:39", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-05T02:02:39", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-05T02:36:40", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-05T13:58:30", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-05T13:58:30", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-05T17:17:54", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-05T17:17:54", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-05T23:40:50", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-05T23:40:50", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-06T01:28:33", + "normal": 3.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-06T01:28:33", + "normal": 3.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-06T14:59:11", + "normal": 2.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-06T14:59:11", + "normal": 2.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-06T20:26:50", + "duration": 3600000, + "extended": 2, + "normal": 6, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-06T20:26:50", + "duration": 3600000, + "extended": 2, + "normal": 6, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-07T00:48:50", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-07T14:09:43", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-07T16:02:12", + "duration": 5400000, + "extended": 3.25, + "normal": 9.75, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-08T18:17:26", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-08T18:29:06", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-08T20:29:43", + "normal": 5.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-08T20:29:43", + "normal": 5.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-08T23:53:16", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-08T23:53:16", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-09T12:19:24", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-09T12:19:24", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-09T16:27:30", + "duration": 3600000, + "extended": 1, + "normal": 5.65, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-09T16:27:30", + "duration": 3600000, + "extended": 1, + "normal": 5.65, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-09T17:50:34", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-10T00:25:49", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-10T17:43:21", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-10T18:08:03", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-11T13:06:32", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-11T19:37:52", + "normal": 7.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-11T19:37:52", + "normal": 7.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-12T00:07:01", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-12T00:07:01", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-12T00:42:51", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-12T07:40:06", + "normal": 3.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-12T07:40:06", + "normal": 3.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-12T08:50:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-12T16:09:42", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-12T21:45:57", + "normal": 6.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-12T21:45:57", + "normal": 6.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-13T10:56:43", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-13T11:42:47", + "normal": 1.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-13T11:42:47", + "normal": 1.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-13T16:33:50", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-13T18:21:41", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-13T22:13:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-13T22:19:30", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-13T22:48:14", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-13T23:08:30", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-14T14:31:41", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-14T15:53:20", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-14T17:37:39", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-14T18:15:11", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-14T20:29:30", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-15T12:18:56", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-15T14:09:52", + "normal": 4.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-15T14:09:52", + "normal": 4.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-15T17:23:04", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-15T17:23:04", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-15T21:15:01", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-15T21:44:35", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-15T22:12:37", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-15T22:57:20", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-15T22:58:49", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-16T09:35:57", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-16T11:31:07", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-16T15:12:49", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-16T15:41:21", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-16T21:04:38", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-17T03:22:39", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-17T03:22:39", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-17T14:09:57", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-17T16:29:43", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-17T16:29:43", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-18T05:26:35", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-18T05:26:35", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-18T08:03:17", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-18T17:58:39", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-18T20:40:22", + "duration": 1800000, + "extended": 5.7, + "normal": 1.9, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-18T20:40:22", + "duration": 1800000, + "extended": 5.7, + "normal": 1.9, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-19T08:36:08", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-19T15:20:39", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-19T18:22:28", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-19T18:54:15", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-19T22:20:06", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-19T22:47:22", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-20T14:23:03", + "duration": 3600000, + "extended": 1.35, + "normal": 5.4, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-20T14:23:03", + "duration": 3600000, + "extended": 1.35, + "normal": 5.4, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-20T15:02:15", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-20T15:50:21", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-21T00:08:35", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-21T00:08:35", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-21T12:12:24", + "normal": 5.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-21T12:12:24", + "normal": 5.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-21T15:13:53", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-21T15:13:53", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-22T16:11:14", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-23T01:06:51", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-23T01:06:51", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-23T10:37:02", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-23T16:18:09", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-23T16:18:09", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-23T16:57:31", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-23T21:30:01", + "duration": 1800000, + "extended": 3.55, + "normal": 1.15, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-23T21:30:01", + "duration": 1800000, + "extended": 3.55, + "normal": 1.15, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-24T08:03:19", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-24T13:21:49", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-24T13:41:26", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-24T15:13:42", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-24T17:30:34", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-24T18:47:01", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-25T00:37:32", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-25T15:27:34", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-25T15:50:46", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-25T18:34:45", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-25T18:34:45", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-26T08:00:02", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-26T15:30:21", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-26T15:30:21", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-26T16:43:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-26T22:55:06", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-27T00:34:23", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-27T16:08:38", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-28T10:22:34", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-28T10:42:12", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-28T11:14:05", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-28T12:22:02", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-28T12:22:02", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-28T17:58:24", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-29T00:59:10", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-29T13:21:48", + "normal": 3.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-29T13:21:48", + "normal": 3.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-29T14:26:37", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-29T14:26:37", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-29T15:29:23", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-29T19:11:00", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-29T21:59:18", + "duration": 10800000, + "extended": 8.65, + "normal": 2.85, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-29T21:59:18", + "duration": 10800000, + "extended": 8.65, + "normal": 2.85, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-30T07:29:04", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-30T11:32:41", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-30T11:32:41", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-30T13:33:42", + "normal": 2.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-30T13:33:42", + "normal": 2.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-30T15:10:57", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-30T16:48:04", + "duration": 2700000, + "expectedDuration": 3600000, + "expectedExtended": 2.65, + "extended": 1.95, + "normal": 4.5, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-30T16:48:04", + "duration": 2700000, + "expectedDuration": 3600000, + "expectedExtended": 2.65, + "extended": 1.95, + "normal": 4.5, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-30T17:35:25", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-31T06:01:14", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-31T08:02:24", + "expectedNormal": 1.8, + "normal": 0, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-31T17:32:27", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-31T17:32:27", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-31T19:24:54", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-31T20:15:14", + "normal": 7.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-31T20:15:14", + "normal": 7.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-07-31T23:11:02", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-01T15:38:03", + "normal": 7.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-02T00:53:24", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-02T00:53:24", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-02T09:42:56", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-02T12:33:40", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-03T13:13:56", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-03T13:13:56", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-03T13:30:33", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-03T19:02:46", + "normal": 7.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-03T19:02:46", + "normal": 7.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-03T23:23:36", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-03T23:30:48", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-04T07:57:10", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-04T17:05:51", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-04T18:14:03", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-05T16:45:27", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-05T19:47:08", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-06T09:25:42", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-06T15:20:44", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-06T16:19:31", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-06T17:07:49", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-06T19:58:23", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-06T19:58:23", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-07T14:38:43", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-07T19:47:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-07T20:51:30", + "normal": 8.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-07T20:51:30", + "normal": 8.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-07T21:31:38", + "normal": 5.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-07T21:31:38", + "normal": 5.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-08T01:05:38", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-08T10:11:09", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-08T15:43:17", + "normal": 6.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-08T15:43:17", + "normal": 6.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-08T19:52:56", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-08T20:57:40", + "duration": 3600000, + "extended": 2, + "normal": 8.95, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-08T20:57:40", + "duration": 3600000, + "extended": 2, + "normal": 8.95, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-09T09:07:47", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-09T16:17:45", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-09T17:24:45", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-11T01:12:55", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-11T18:24:34", + "normal": 5.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-11T18:24:34", + "normal": 5.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-11T19:04:48", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-11T20:30:46", + "normal": 0.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-11T20:30:46", + "normal": 0.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-12T10:04:06", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-13T17:30:51", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-13T18:15:01", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-13T18:15:01", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-13T18:43:29", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-14T15:37:44", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-15T01:47:54", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-15T13:59:56", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-15T14:41:43", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-15T14:44:38", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-15T21:54:18", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-16T15:51:57", + "normal": 7.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-16T15:51:57", + "normal": 7.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-16T16:23:22", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-16T20:59:44", + "normal": 7.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-16T20:59:44", + "normal": 7.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-16T22:28:09", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-17T13:43:39", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-17T15:22:58", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-17T20:43:00", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-17T20:43:00", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-17T22:37:07", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-17T22:37:07", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-18T12:51:55", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-18T15:37:39", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-18T15:37:39", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-18T16:20:47", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-18T16:23:34", + "expectedNormal": 1, + "normal": 0, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-18T16:23:47", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-19T01:18:52", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-19T18:35:04", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-19T18:35:04", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-19T18:45:16", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-19T19:19:18", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-19T19:49:49", + "normal": 9.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-20T13:23:57", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-20T13:23:57", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-20T18:56:03", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-20T18:56:03", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-21T18:29:04", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-21T18:29:04", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-21T20:46:21", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-21T20:46:21", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-22T21:10:05", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-22T21:58:04", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-22T22:02:55", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-23T18:27:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-23T18:27:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-23T20:31:41", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-23T20:59:54", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-23T23:21:11", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-24T10:24:29", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-24T17:07:32", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-24T17:33:08", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-24T18:35:51", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-25T14:07:13", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-25T17:12:17", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-25T21:24:58", + "normal": 8.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-26T11:35:34", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-26T11:48:12", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-26T12:08:19", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-26T16:13:11", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-26T22:12:41", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-27T01:27:13", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-27T16:56:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-27T19:56:41", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-27T20:22:28", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-27T20:57:07", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-28T07:42:06", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-28T07:42:06", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-28T09:05:30", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-28T09:05:30", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-28T09:54:05", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-28T09:54:05", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-28T14:01:25", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-28T15:50:43", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-28T20:59:49", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-28T21:29:58", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-29T01:28:07", + "expectedNormal": 3, + "normal": 0, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-29T01:28:23", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-29T05:09:40", + "expectedNormal": 2.55, + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-29T05:09:40", + "expectedNormal": 2.55, + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-29T05:18:26", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-29T05:18:26", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-29T06:58:48", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-29T07:02:43", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-29T13:23:14", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-29T21:18:42", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-29T21:18:42", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-30T15:27:04", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-30T15:45:46", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-30T16:03:48", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-30T21:27:24", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-31T00:32:49", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-31T00:32:49", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-08-31T14:12:55", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-01T00:10:43", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-01T00:20:00", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-01T01:11:31", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-01T18:11:06", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-01T18:59:49", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-01T18:59:49", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-01T23:21:40", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T01:17:05", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T07:22:03", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T09:19:07", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T15:32:12", + "duration": 3600000, + "extended": 1.65, + "normal": 3.8, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T15:32:12", + "duration": 3600000, + "extended": 1.65, + "normal": 3.8, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T17:09:29", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T19:39:58", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T19:39:58", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T20:38:24", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T20:38:24", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T20:44:02", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-02T21:40:20", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-03T00:20:40", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-03T00:20:40", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-03T06:42:57", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-03T14:08:27", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-03T14:48:55", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-03T17:14:46", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-03T22:34:31", + "normal": 5.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-04T00:28:34", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-04T06:09:22", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-04T14:45:39", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-04T18:24:53", + "normal": 10.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-05T01:06:54", + "normal": 6.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-05T16:22:33", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-05T16:58:48", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-05T21:45:50", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-06T00:55:25", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-06T15:41:42", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-06T15:45:31", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-06T16:47:53", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-06T21:15:40", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-06T21:15:40", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-07T19:12:03", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-07T19:57:42", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-07T20:27:57", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-07T23:09:54", + "normal": 10.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-08T06:49:54", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-08T13:38:14", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-08T19:03:48", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-08T21:12:03", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-08T22:21:55", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-09T01:19:46", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-09T15:05:45", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-09T22:54:59", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-09T23:26:51", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-10T16:45:44", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-10T17:22:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-10T20:02:24", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-10T22:48:01", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-10T23:18:10", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-11T17:11:53", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-11T23:15:24", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-12T00:04:13", + "normal": 2.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-12T00:04:13", + "normal": 2.25, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-12T00:28:22", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-12T15:21:56", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-13T15:59:02", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-13T22:06:29", + "normal": 6.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-14T11:11:32", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-14T13:09:35", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-14T19:24:39", + "normal": 10.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-14T19:24:39", + "normal": 10.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-15T15:36:19", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-15T21:46:47", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-15T21:46:47", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-15T22:10:16", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-16T15:44:33", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-16T21:36:53", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-17T15:59:12", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-17T16:08:56", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-17T21:09:25", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-17T21:09:25", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-18T09:37:49", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-18T18:20:54", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-18T18:51:09", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-19T13:27:26", + "duration": 3600000, + "extended": 0.55, + "normal": 0.25, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-19T13:27:26", + "duration": 3600000, + "extended": 0.55, + "normal": 0.25, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-19T14:53:40", + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-19T14:53:40", + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-19T15:24:30", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-20T18:32:41", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-20T21:29:36", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-21T15:35:49", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-21T15:35:49", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-21T21:03:52", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-21T22:39:49", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-22T11:25:56", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-22T13:19:40", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-22T17:25:35", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-22T19:59:31", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-22T22:50:19", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-23T11:45:40", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-23T11:47:49", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-23T12:07:32", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-23T15:08:45", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-23T20:33:01", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-23T22:00:40", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-24T06:08:59", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-24T08:33:59", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-24T11:22:33", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-24T21:52:26", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-24T22:08:46", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-25T16:52:46", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-25T20:23:33", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-25T20:36:44", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-26T07:18:20", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-26T10:15:04", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-26T16:11:43", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-26T19:25:09", + "normal": 6.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-26T21:22:26", + "normal": 1.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-26T21:22:26", + "normal": 1.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-27T12:14:07", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-27T13:57:02", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-27T14:09:20", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-27T15:29:54", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-27T20:48:41", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-27T21:12:09", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-27T21:20:49", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-27T21:49:25", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-28T04:50:11", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-28T07:40:45", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-28T12:06:19", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-28T15:46:19", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-28T15:46:19", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-28T21:47:01", + "normal": 12.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-28T21:47:01", + "normal": 12.35, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-29T01:12:35", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-29T02:08:17", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-29T02:59:26", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-29T14:42:33", + "normal": 7.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-29T14:42:33", + "normal": 7.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-29T15:02:43", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-29T15:12:10", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-29T19:10:18", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-29T19:46:49", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-30T11:29:40", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-30T13:56:15", + "normal": 5.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-30T15:42:59", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-30T22:53:22", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-30T23:05:22", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-09-30T23:35:16", + "normal": 7.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-01T14:27:43", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-01T16:04:42", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-01T22:28:45", + "normal": 6.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-01T22:28:45", + "normal": 6.85, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-02T17:01:12", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-02T17:01:12", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-02T18:18:32", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-02T22:08:17", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-02T22:56:37", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-03T07:44:00", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-03T08:42:58", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-03T15:24:28", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-03T15:24:28", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-03T17:53:59", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-03T17:53:59", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-03T19:00:37", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-03T22:17:33", + "normal": 7.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-03T22:17:33", + "normal": 7.65, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-04T09:52:11", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-04T12:55:58", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-04T12:55:58", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-04T15:12:11", + "normal": 6.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-04T20:09:22", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-05T03:27:19", + "normal": 4.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-05T03:27:19", + "normal": 4.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-05T19:22:47", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-05T19:22:47", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-05T22:39:45", + "normal": 10.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-05T22:39:45", + "normal": 10.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-06T06:12:37", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-06T06:12:37", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-06T12:42:06", + "normal": 8.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-06T15:32:00", + "expectedNormal": 4.7, + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-06T19:07:20", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-06T19:39:58", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-07T00:20:47", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-07T05:30:49", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-07T08:21:15", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-07T22:44:14", + "normal": 8.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-08T06:58:25", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-08T08:16:59", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-08T13:52:10", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-08T19:52:08", + "normal": 5.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-08T19:52:08", + "normal": 5.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-09T06:26:22", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-09T06:26:22", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-09T07:43:04", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-09T15:08:46", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-09T15:54:44", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-09T23:03:47", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-09T23:38:04", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-09T23:38:04", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-10T16:02:43", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-10T22:56:35", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-10T22:56:35", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-10T23:35:59", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-11T15:03:25", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-11T15:03:25", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-11T16:13:04", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-11T21:19:03", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-11T21:19:03", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-12T07:22:58", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-12T15:16:54", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-12T15:16:54", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-12T15:54:25", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-12T21:11:04", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-12T21:11:04", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-13T13:15:55", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-13T13:18:43", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-13T13:18:43", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-13T16:26:19", + "normal": 6.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-13T16:26:19", + "normal": 6.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-13T20:33:47", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-13T20:33:47", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-13T20:49:06", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-13T21:24:48", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-13T23:18:40", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-13T23:45:17", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-14T00:25:53", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-14T01:10:52", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-14T12:00:00", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-14T15:36:08", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-14T16:01:10", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-14T19:58:59", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-14T20:51:48", + "normal": 8.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-14T20:51:48", + "normal": 8.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-14T21:40:26", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-14T23:14:13", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-15T00:33:52", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-15T00:33:52", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-15T08:45:17", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-15T15:49:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-15T21:53:25", + "normal": 8.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-15T21:53:25", + "normal": 8.75, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-15T22:38:18", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-16T16:47:33", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-16T22:22:47", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-16T23:27:48", + "normal": 14.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-17T15:50:12", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-17T15:52:31", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-18T14:12:19", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-18T15:09:54", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-18T15:27:12", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-18T15:57:46", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-18T23:28:05", + "normal": 8.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-18T23:28:05", + "normal": 8.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-19T00:10:14", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-19T00:46:24", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-19T01:11:02", + "normal": 5.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-19T14:59:14", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-19T16:28:00", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-19T22:00:22", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-19T23:24:34", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-20T17:39:33", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-20T19:27:43", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-20T20:07:49", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-20T20:43:12", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-20T21:54:33", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-21T14:16:42", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-21T20:42:35", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-22T12:14:12", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-23T07:12:15", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-23T11:12:32", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-23T12:36:16", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-23T12:50:53", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-23T14:17:09", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-24T10:47:06", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-24T14:20:06", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-24T16:11:40", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-25T00:18:43", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-25T19:12:42", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-25T19:12:42", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-25T20:42:26", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-25T20:42:26", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-26T18:49:01", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-27T18:11:11", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-27T20:47:51", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-28T13:28:57", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-28T13:31:35", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-28T13:43:39", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-28T18:08:08", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-29T03:56:45", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-29T03:56:45", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-29T15:09:37", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-29T15:58:27", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-29T15:58:27", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-30T02:57:09", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-30T16:34:05", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-30T19:17:07", + "expectedNormal": 8, + "normal": 6.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-30T23:28:05", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-10-31T20:19:12", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-01T16:10:05", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-01T23:01:05", + "normal": 3.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-01T23:01:05", + "normal": 3.15, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-02T17:16:10", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-02T23:46:20", + "normal": 8.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-03T12:56:37", + "normal": 6.1, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-03T13:09:30", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-03T16:07:02", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-03T20:10:25", + "duration": 3600000, + "extended": 2.2, + "normal": 12.3, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-03T20:10:25", + "duration": 3600000, + "extended": 2.2, + "normal": 12.3, + "subType": "dual/square", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-04T05:00:38", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-04T05:00:38", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-04T12:35:17", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-04T12:35:17", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-04T15:46:38", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-04T15:46:38", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-04T22:01:14", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-05T09:37:58", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "Some-Pump", + "deviceTime": "2018-11-05T13:19:18", + "normal": 2, + "subType": "normal", + }, +} From ef7c7339ce06e0c3b4d7f8485eda4a07dd4d7856 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 24 Jul 2024 15:10:11 +1200 Subject: [PATCH 361/413] cleanup CompareDatasets --- .../utils/data_verify.go | 70 ++++++++++++------- .../utils/data_verify_test.go | 37 +++++----- 2 files changed, 63 insertions(+), 44 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index 6c5b900252..e35a8828f3 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -168,38 +168,56 @@ func (m *DataVerify) WriteBlobIDs() error { return nil } -func CompareDatasets(platformSet []map[string]interface{}, jellyfishSet []map[string]interface{}) ([]map[string]interface{}, []map[string]interface{}, []map[string]interface{}) { - platformMissing := []map[string]interface{}{} - platformExtras := []map[string]interface{}{} - platformDuplicates := []map[string]interface{}{} - pfCounts := map[string]int{} +const ( + PlatformExtra = "extra" + PlatformDuplicate = "duplicate" + PlatformMissing = "missing" +) + +func CompareDatasets(platformSet []map[string]interface{}, jellyfishSet []map[string]interface{}) map[string][]map[string]interface{} { + + diffs := map[string][]map[string]interface{}{ + PlatformExtra: {}, + PlatformDuplicate: {}, + PlatformMissing: {}, + } + const deviceTimeName = "deviceTime" + pfCounts := map[string][]map[string]interface{}{} jfCounts := map[string]int{} for _, jDatum := range jellyfishSet { - jfCounts[fmt.Sprintf("%v", jDatum["deviceTime"])] += 1 + jfCounts[fmt.Sprintf("%v", jDatum[deviceTimeName])] += 1 } for _, pDatum := range platformSet { - pfCounts[fmt.Sprintf("%v", pDatum["deviceTime"])] += 1 - if pfCounts[fmt.Sprintf("%v", pDatum["deviceTime"])] > 1 { - platformDuplicates = append(platformDuplicates, pDatum) - continue + + strDatumTime := fmt.Sprintf("%v", pDatum[deviceTimeName]) + + if len(pfCounts[strDatumTime]) == 0 { + pfCounts[strDatumTime] = []map[string]interface{}{pDatum} + } else if len(pfCounts[strDatumTime]) >= 1 { + pfCounts[strDatumTime] = append(pfCounts[strDatumTime], pDatum) + + for _, existingPDatum := range pfCounts[strDatumTime] { + if fmt.Sprintf("%v", existingPDatum) == fmt.Sprintf("%v", pDatum) { + diffs[PlatformDuplicate] = append(diffs[PlatformDuplicate], pDatum) + break + } + } } - // jellyfish does not have platform dp then its an extra - if jfCounts[fmt.Sprintf("%v", pDatum["deviceTime"])] == 0 { - platformExtras = append(platformExtras, pDatum) + if jfCounts[fmt.Sprintf("%v", pDatum[deviceTimeName])] == 0 { + diffs[PlatformExtra] = append(diffs[PlatformExtra], pDatum) } } for _, jDatum := range jellyfishSet { - if pfCounts[fmt.Sprintf("%v", jDatum["deviceTime"])] >= 1 { + if len(pfCounts[fmt.Sprintf("%v", jDatum[deviceTimeName])]) >= 1 { continue } - platformMissing = append(platformMissing, jDatum) + diffs[PlatformMissing] = append(diffs[PlatformMissing], jDatum) } - - return platformMissing, platformDuplicates, platformExtras + return diffs } var dataTypePathIgnored = map[string][]string{ @@ -231,20 +249,20 @@ func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUpload pfSet := platformDataset[dType] comparePath := filepath.Join(".", "_compare", fmt.Sprintf("%s_%s", platformUploadID, jellyfishUploadID)) log.Printf("data written to %s", comparePath) - missing, duplicates, extras := CompareDatasets(pfSet, jfSet) - if len(missing) > 0 { - writeFileData(missing, comparePath, fmt.Sprintf("platform_missing_%s.json", dType), true) + setDifferences := CompareDatasets(pfSet, jfSet) + if len(setDifferences[PlatformMissing]) > 0 { + writeFileData(setDifferences[PlatformMissing], comparePath, fmt.Sprintf("%s_platform_missing.json", dType), true) } - if len(duplicates) > 0 { - writeFileData(duplicates, comparePath, fmt.Sprintf("platform_duplicates_%s.json", dType), true) + if len(setDifferences[PlatformDuplicate]) > 0 { + writeFileData(setDifferences[PlatformDuplicate], comparePath, fmt.Sprintf("%s_platform_duplicates.json", dType), true) } - if len(extras) > 0 { - writeFileData(extras, comparePath, fmt.Sprintf("platform_extra_%s.json", dType), true) + if len(setDifferences[PlatformExtra]) > 0 { + writeFileData(setDifferences[PlatformExtra], comparePath, fmt.Sprintf("%s_platform_extra.json", dType), true) } if len(pfSet) != len(jfSet) { log.Printf("NOTE: datasets mismatch platform (%d) vs jellyfish (%d)", len(pfSet), len(jfSet)) - writeFileData(jfSet, comparePath, fmt.Sprintf("raw_%s_jellyfish_%s.json", dType, jellyfishUploadID), true) - writeFileData(pfSet, comparePath, fmt.Sprintf("raw_%s_platform_%s.json", dType, platformUploadID), true) + writeFileData(jfSet, comparePath, fmt.Sprintf("%s_jellyfish_datums.json", dType), true) + writeFileData(pfSet, comparePath, fmt.Sprintf("%s_platform_datums.json", dType), true) break } differences, err := CompareDatasetDatums(pfSet, jfSet, dataTypePathIgnored[dType]...) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify_test.go b/migrations/20231128_jellyfish_migration/utils/data_verify_test.go index 946b9838df..5fea0efd7d 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify_test.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify_test.go @@ -81,17 +81,17 @@ var _ = Describe("DataVerify", func() { var _ = Describe("CompareDatasets", func() { It("will have no differences when that same and no dups", func() { - missing, duplicates, extras := utils.CompareDatasets(test.JFBolusSet, test.JFBolusSet) - Expect(len(duplicates)).To(Equal(0)) - Expect(len(extras)).To(Equal(0)) - Expect(len(missing)).To(Equal(0)) + dSetDifference := utils.CompareDatasets(test.JFBolusSet, test.JFBolusSet) + Expect(len(dSetDifference[utils.PlatformDuplicate])).To(Equal(0)) + Expect(len(dSetDifference[utils.PlatformExtra])).To(Equal(0)) + Expect(len(dSetDifference[utils.PlatformMissing])).To(Equal(0)) }) It("will find duplicates in the platform dataset", func() { - missing, duplicates, extras := utils.CompareDatasets(test.PlatformBolusSet, test.JFBolusSet) - Expect(len(duplicates)).To(Equal(395)) - Expect(len(extras)).To(Equal(0)) - Expect(len(missing)).To(Equal(0)) + dSetDifference := utils.CompareDatasets(test.PlatformBolusSet, test.JFBolusSet) + Expect(len(dSetDifference[utils.PlatformDuplicate])).To(Equal(395)) + Expect(len(dSetDifference[utils.PlatformExtra])).To(Equal(0)) + Expect(len(dSetDifference[utils.PlatformMissing])).To(Equal(0)) }) It("will find extras in the platform dataset", func() { @@ -101,11 +101,11 @@ var _ = Describe("DataVerify", func() { "deviceTime": "2023-01-18T12:00:00", } - missing, duplicates, extras := utils.CompareDatasets(append(test.PlatformBolusSet, expectedExtra), test.JFBolusSet) - Expect(len(duplicates)).To(Equal(395)) - Expect(len(extras)).To(Equal(1)) - Expect(extras[0]).To(Equal(expectedExtra)) - Expect(len(missing)).To(Equal(0)) + dSetDifference := utils.CompareDatasets(append(test.PlatformBolusSet, expectedExtra), test.JFBolusSet) + Expect(len(dSetDifference[utils.PlatformDuplicate])).To(Equal(395)) + Expect(len(dSetDifference[utils.PlatformExtra])).To(Equal(1)) + Expect(dSetDifference[utils.PlatformExtra][0]).To(Equal(expectedExtra)) + Expect(len(dSetDifference[utils.PlatformMissing])).To(Equal(0)) }) It("will find missing in the platform dataset", func() { @@ -115,11 +115,12 @@ var _ = Describe("DataVerify", func() { "deviceTime": "2023-01-18T12:00:00", } - missing, duplicates, extras := utils.CompareDatasets(test.PlatformBolusSet, append(test.JFBolusSet, expectedMissing)) - Expect(len(duplicates)).To(Equal(395)) - Expect(len(extras)).To(Equal(0)) - Expect(len(missing)).To(Equal(1)) - Expect(missing[0]).To(Equal(expectedMissing)) + dSetDifference := utils.CompareDatasets(test.PlatformBolusSet, append(test.JFBolusSet, expectedMissing)) + + Expect(len(dSetDifference[utils.PlatformDuplicate])).To(Equal(395)) + Expect(len(dSetDifference[utils.PlatformExtra])).To(Equal(0)) + Expect(len(dSetDifference[utils.PlatformMissing])).To(Equal(1)) + Expect(dSetDifference[utils.PlatformMissing][0]).To(Equal(expectedMissing)) }) }) From db10afe6332f23d20b9b637e72ca842d37a67723 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 24 Jul 2024 16:00:43 +1200 Subject: [PATCH 362/413] fix for duplicates CompareDatasets --- .../utils/data_verify.go | 10 +++++++--- .../utils/data_verify_test.go | 13 +++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index e35a8828f3..e58a92aa16 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -197,14 +197,18 @@ func CompareDatasets(platformSet []map[string]interface{}, jellyfishSet []map[st if len(pfCounts[strDatumTime]) == 0 { pfCounts[strDatumTime] = []map[string]interface{}{pDatum} } else if len(pfCounts[strDatumTime]) >= 1 { - pfCounts[strDatumTime] = append(pfCounts[strDatumTime], pDatum) - for _, existingPDatum := range pfCounts[strDatumTime] { - if fmt.Sprintf("%v", existingPDatum) == fmt.Sprintf("%v", pDatum) { + currentItems := pfCounts[strDatumTime] + for _, item := range currentItems { + if fmt.Sprintf("%v", item) == fmt.Sprintf("%v", pDatum) { diffs[PlatformDuplicate] = append(diffs[PlatformDuplicate], pDatum) + continue + } else { + diffs[PlatformExtra] = append(diffs[PlatformExtra], pDatum) break } } + pfCounts[strDatumTime] = append(pfCounts[strDatumTime], pDatum) } if jfCounts[fmt.Sprintf("%v", pDatum[deviceTimeName])] == 0 { diffs[PlatformExtra] = append(diffs[PlatformExtra], pDatum) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify_test.go b/migrations/20231128_jellyfish_migration/utils/data_verify_test.go index 5fea0efd7d..a03754cc5e 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify_test.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify_test.go @@ -94,6 +94,19 @@ var _ = Describe("DataVerify", func() { Expect(len(dSetDifference[utils.PlatformMissing])).To(Equal(0)) }) + It("will find extras in the platform dataset that have duplicate timestamp but not data", func() { + + duplicateTimeStamp := map[string]interface{}{ + "extra": true, + "deviceTime": "2018-01-03T13:07:10", + } + + dSetDifference := utils.CompareDatasets(append(test.PlatformBolusSet, duplicateTimeStamp), test.JFBolusSet) + Expect(len(dSetDifference[utils.PlatformDuplicate])).To(Equal(395)) + Expect(len(dSetDifference[utils.PlatformExtra])).To(Equal(1)) + Expect(len(dSetDifference[utils.PlatformMissing])).To(Equal(0)) + }) + It("will find extras in the platform dataset", func() { expectedExtra := map[string]interface{}{ From 8fcba34ffcc53e0485d737c102dc08df0172da40 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 25 Jul 2024 09:56:51 +1200 Subject: [PATCH 363/413] updates to find missing datums from platform records --- .../utils/data_verify.go | 26 +- .../utils/data_verify_test.go | 22 +- .../utils/test/data_verify.go | 67436 +++++++++++++++- 3 files changed, 64031 insertions(+), 3453 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go index e58a92aa16..55f815e9f6 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify.go @@ -182,12 +182,19 @@ func CompareDatasets(platformSet []map[string]interface{}, jellyfishSet []map[st PlatformMissing: {}, } const deviceTimeName = "deviceTime" + type deviceTimeDatums map[string][]map[string]interface{} - pfCounts := map[string][]map[string]interface{}{} - jfCounts := map[string]int{} + pfCounts := deviceTimeDatums{} + jfCounts := deviceTimeDatums{} for _, jDatum := range jellyfishSet { - jfCounts[fmt.Sprintf("%v", jDatum[deviceTimeName])] += 1 + strDatumTime := fmt.Sprintf("%v", jDatum[deviceTimeName]) + + if len(jfCounts[strDatumTime]) == 0 { + jfCounts[strDatumTime] = []map[string]interface{}{jDatum} + } else if len(jfCounts[strDatumTime]) >= 1 { + jfCounts[strDatumTime] = append(jfCounts[strDatumTime], jDatum) + } } for _, pDatum := range platformSet { @@ -210,16 +217,18 @@ func CompareDatasets(platformSet []map[string]interface{}, jellyfishSet []map[st } pfCounts[strDatumTime] = append(pfCounts[strDatumTime], pDatum) } - if jfCounts[fmt.Sprintf("%v", pDatum[deviceTimeName])] == 0 { + if len(jfCounts[fmt.Sprintf("%v", pDatum[deviceTimeName])]) == 0 { diffs[PlatformExtra] = append(diffs[PlatformExtra], pDatum) } } - for _, jDatum := range jellyfishSet { - if len(pfCounts[fmt.Sprintf("%v", jDatum[deviceTimeName])]) >= 1 { - continue + for jfDeviceTimeStr, jDatums := range jfCounts { + if len(pfCounts[jfDeviceTimeStr]) < len(jfCounts[jfDeviceTimeStr]) { + //NOTE: more of an indicator there are missing records ... + for i := len(pfCounts[jfDeviceTimeStr]); i < len(jfCounts[jfDeviceTimeStr]); i++ { + diffs[PlatformMissing] = append(diffs[PlatformMissing], jDatums[i]) + } } - diffs[PlatformMissing] = append(diffs[PlatformMissing], jDatum) } return diffs } @@ -277,6 +286,5 @@ func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUpload writeFileData(differences, comparePath, fmt.Sprintf("%s_datum_diff.json", dType), true) } } - return nil } diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify_test.go b/migrations/20231128_jellyfish_migration/utils/data_verify_test.go index a03754cc5e..0a9b45c019 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_verify_test.go +++ b/migrations/20231128_jellyfish_migration/utils/data_verify_test.go @@ -95,7 +95,6 @@ var _ = Describe("DataVerify", func() { }) It("will find extras in the platform dataset that have duplicate timestamp but not data", func() { - duplicateTimeStamp := map[string]interface{}{ "extra": true, "deviceTime": "2018-01-03T13:07:10", @@ -108,7 +107,6 @@ var _ = Describe("DataVerify", func() { }) It("will find extras in the platform dataset", func() { - expectedExtra := map[string]interface{}{ "extra": 3, "deviceTime": "2023-01-18T12:00:00", @@ -121,19 +119,17 @@ var _ = Describe("DataVerify", func() { Expect(len(dSetDifference[utils.PlatformMissing])).To(Equal(0)) }) - It("will find missing in the platform dataset", func() { + It("will find datums that are missing in the platform dataset", func() { + platformBasals := test.GetPlatformBasalData() + jellyfishBasals := test.GetJFBasalData() - expectedMissing := map[string]interface{}{ - "missing": 3, - "deviceTime": "2023-01-18T12:00:00", - } + Expect(len(platformBasals)).To(Equal(3123)) + Expect(len(jellyfishBasals)).To(Equal(3386)) - dSetDifference := utils.CompareDatasets(test.PlatformBolusSet, append(test.JFBolusSet, expectedMissing)) - - Expect(len(dSetDifference[utils.PlatformDuplicate])).To(Equal(395)) - Expect(len(dSetDifference[utils.PlatformExtra])).To(Equal(0)) - Expect(len(dSetDifference[utils.PlatformMissing])).To(Equal(1)) - Expect(dSetDifference[utils.PlatformMissing][0]).To(Equal(expectedMissing)) + dSetDifference := utils.CompareDatasets(platformBasals, jellyfishBasals) + Expect(len(dSetDifference[utils.PlatformDuplicate])).To(Equal(5)) + Expect(len(dSetDifference[utils.PlatformExtra])).To(Equal(4)) + Expect(len(dSetDifference[utils.PlatformMissing])).To(Equal(263)) }) }) diff --git a/migrations/20231128_jellyfish_migration/utils/test/data_verify.go b/migrations/20231128_jellyfish_migration/utils/test/data_verify.go index 470de45365..a089143b96 100644 --- a/migrations/20231128_jellyfish_migration/utils/test/data_verify.go +++ b/migrations/20231128_jellyfish_migration/utils/test/data_verify.go @@ -1,817 +1,819 @@ package test +import "encoding/json" + var JFBolusSet = []map[string]interface{}{ { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-11T05:48:32", "normal": 1.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-11T08:48:43", "normal": 2.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-11T17:07:35", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-11T17:48:17", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-11T22:16:32", "expectedNormal": 6, "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T02:48:01", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T02:57:56", "normal": 2.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T03:45:23", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T04:02:33", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T04:07:54", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T12:10:52", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T13:43:31", "normal": 0.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T18:55:53", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T22:06:00", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-13T00:07:54", "normal": 6.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-13T15:36:15", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-13T19:15:32", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-13T23:32:46", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-14T02:56:18", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-14T15:05:16", "normal": 5.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-14T18:45:59", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-14T21:06:30", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-15T02:10:44", "expectedNormal": 6, "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-15T10:11:52", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-15T10:21:08", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-15T10:52:13", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-15T18:51:32", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-15T20:32:07", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-15T20:43:33", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-15T21:26:55", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-16T07:56:57", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-16T15:32:09", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-16T16:04:19", "expectedNormal": 3.7, "normal": 0.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-16T16:04:45", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-16T16:23:41", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-16T16:35:34", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-16T16:58:46", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-16T22:04:48", "normal": 4.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T07:49:22", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T07:58:22", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T08:31:44", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T09:25:59", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T15:19:35", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T15:41:16", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T16:13:32", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T16:51:39", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T17:36:34", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T22:24:30", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-18T00:26:16", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-18T00:57:05", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-18T09:39:10", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-18T13:26:16", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-18T15:56:31", "normal": 0.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-18T16:46:24", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-18T17:16:59", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-19T01:21:09", "normal": 2.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-19T01:51:44", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-19T18:01:16", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-19T19:01:35", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-19T22:24:42", "normal": 3.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-19T22:27:54", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-19T23:16:39", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-20T11:50:37", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-20T13:36:40", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-20T18:31:12", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-20T19:04:49", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-20T19:13:53", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-21T14:16:39", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-22T00:12:03", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-22T13:54:39", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-22T20:02:33", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-22T20:09:02", "normal": 7.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-22T20:42:46", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-22T20:51:20", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-23T14:51:38", "normal": 5.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-23T17:40:56", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-24T10:57:40", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-24T13:49:15", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-24T20:29:08", "normal": 5.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-24T23:20:14", "normal": 2.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T02:11:25", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T03:41:15", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T03:49:26", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T11:34:54", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T11:36:30", "expectedNormal": 3.7, "normal": 2.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T11:39:54", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T18:55:44", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T21:00:32", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T21:56:23", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T22:40:16", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-26T00:47:19", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-26T11:19:24", "normal": 6.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-26T18:22:46", "normal": 9.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-26T20:06:31", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-26T21:00:39", "normal": 4.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-27T00:43:11", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-27T00:54:23", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-27T01:21:34", "normal": 0.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-27T07:02:47", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-27T08:20:19", "normal": 3.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-27T11:57:25", "normal": 9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-27T18:36:04", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-27T20:18:11", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-28T10:55:51", "normal": 10.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-28T13:31:27", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-28T17:47:15", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-28T18:58:25", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-28T20:20:09", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T05:47:36", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T11:04:51", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T11:17:10", "expectedNormal": 5, "normal": 0.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T11:17:44", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T11:59:21", "normal": 4.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T12:33:05", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T16:04:51", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T18:22:02", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T20:35:15", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-30T00:19:10", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-30T01:14:53", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-30T11:38:04", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-30T14:10:30", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-30T18:11:40", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-30T19:40:37", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-30T22:39:58", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-01T09:55:37", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-01T12:02:23", "normal": 4.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-01T12:11:07", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-01T15:03:11", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-01T23:36:08", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-02T13:42:27", "normal": 2.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-03T08:36:32", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-03T12:46:16", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-03T14:31:00", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-03T19:01:03", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-03T19:13:12", "duration": 3600000, "extended": 1.35, @@ -819,1452 +821,1452 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-03T23:09:17", "expectedNormal": 5.6, "normal": 4.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-04T01:32:34", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-04T13:31:48", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-04T23:45:20", "normal": 5.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-05T05:38:22", "normal": 4.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-05T13:05:36", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-05T18:04:44", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-05T22:31:49", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-06T09:05:49", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-06T19:44:34", "normal": 3.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-07T11:30:47", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-07T17:39:58", "normal": 3.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-08T09:36:46", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-08T12:09:06", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-08T13:51:33", "normal": 1.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-08T22:47:22", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-08T23:06:37", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-08T23:34:05", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-09T11:51:03", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-09T18:28:48", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-09T18:41:43", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-09T19:46:42", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-09T22:41:34", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-10T03:05:28", "normal": 1.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-10T11:34:38", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-10T14:55:50", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-10T15:23:08", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-10T19:28:56", "normal": 8.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-10T21:16:11", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-10T22:17:25", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-11T14:30:42", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-11T19:17:18", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-12T13:15:43", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-12T14:37:19", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-12T20:45:23", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-12T21:17:50", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-12T22:07:50", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-12T23:57:33", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-13T10:28:04", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-13T17:42:12", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-14T04:31:16", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-14T09:40:01", "normal": 3.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-14T15:57:40", "normal": 2.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-14T17:26:58", "normal": 2.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-15T05:49:43", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-15T09:42:54", "normal": 2.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-15T15:42:11", "normal": 4.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-15T17:58:05", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-15T20:36:40", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-15T21:54:57", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-16T02:10:54", "normal": 5.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-16T05:18:35", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-16T17:03:43", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-16T21:17:40", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-16T21:27:12", "expectedNormal": 1.8, "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-17T15:02:37", "normal": 5.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-18T08:53:51", "normal": 3.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-18T14:07:21", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-19T00:37:12", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-20T22:52:22", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-21T16:04:44", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-21T17:31:36", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-22T20:34:13", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T00:32:29", "normal": 3.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T02:01:53", "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T13:25:12", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T14:45:29", "normal": 5.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T15:17:41", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T15:27:27", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T20:51:42", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T22:28:05", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-24T15:45:49", "normal": 5.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-24T17:30:54", "normal": 5.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-25T03:24:31", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-25T17:51:24", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-25T18:17:02", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-25T18:44:42", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-25T19:06:09", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-26T04:38:05", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-26T21:52:20", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-26T22:10:35", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-27T00:35:55", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-27T12:09:08", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-27T13:12:31", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-27T22:06:04", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-27T23:57:59", "normal": 8.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-28T13:41:05", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-28T21:53:48", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-28T22:38:58", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-28T23:35:34", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-29T01:10:10", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-29T13:28:49", "normal": 7.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-29T15:31:09", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-29T15:47:25", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-29T20:49:26", "normal": 10.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-29T23:31:22", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T01:14:51", "normal": 2.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T10:07:54", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T14:41:41", "normal": 3.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T15:36:28", "normal": 0.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T17:21:07", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T17:47:07", "normal": 1.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T19:43:22", "normal": 10.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T21:42:19", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T23:34:45", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T23:57:13", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-31T14:15:24", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-31T15:37:20", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-31T16:37:23", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-31T20:22:35", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-31T22:50:28", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-01T00:18:37", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-01T03:28:56", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-01T08:23:20", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-01T17:09:58", "normal": 5.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-01T20:29:55", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-01T21:39:29", "normal": 11.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T01:37:45", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T09:05:27", "normal": 4.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T09:28:02", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T15:17:44", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T17:05:07", "normal": 5.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T21:57:29", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T22:31:41", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T23:58:14", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-03T06:23:16", "normal": 4.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-03T13:07:10", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-03T17:36:24", "normal": 1.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-03T19:19:53", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-04T20:39:32", "normal": 12.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-04T23:27:30", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-05T11:26:40", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-05T14:39:47", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-05T21:24:08", "normal": 12.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-05T23:47:57", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-06T10:29:13", "normal": 2.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-07T02:43:11", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-07T15:29:23", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-07T15:53:38", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-08T00:50:58", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-08T02:22:40", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-08T10:49:22", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-08T12:10:15", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-08T16:06:15", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-08T21:00:55", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-08T22:52:11", "normal": 13.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-09T06:48:05", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-09T11:57:20", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-09T14:50:09", "expectedNormal": 7.1, "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-09T15:09:57", "expectedNormal": 5.3, "normal": 0, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-09T15:10:07", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-09T15:45:24", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-09T19:08:06", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-10T00:20:48", "normal": 3.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-10T09:57:07", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-10T15:19:38", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-10T19:51:35", "normal": 6.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-10T21:04:03", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-11T17:21:27", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-11T23:50:01", "normal": 9.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-12T14:21:27", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-13T01:22:50", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-13T09:16:42", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-13T09:45:20", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-13T17:59:12", "normal": 6.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-13T19:51:42", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-14T01:09:36", "normal": 5.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-14T15:27:34", "normal": 6.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-14T15:37:30", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-14T19:52:15", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-14T22:44:38", "normal": 11, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-14T23:04:59", "expectedNormal": 8.7, "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-15T08:08:01", "normal": 5.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-15T17:50:26", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-15T18:22:34", "normal": 4.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-15T22:12:43", "normal": 4.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-16T05:28:57", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-16T19:06:03", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-18T00:44:27", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-18T15:16:10", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-18T21:34:19", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-19T15:18:48", "normal": 7.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-19T18:24:25", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-19T21:40:18", "normal": 5.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-20T01:57:09", "normal": 5.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-20T05:21:15", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-20T14:43:26", "normal": 2.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-20T20:23:29", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-20T23:15:21", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-21T01:47:25", "normal": 3.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-21T16:32:58", "normal": 4.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-21T21:12:41", "normal": 9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-22T13:07:23", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-22T13:24:37", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-22T13:38:43", "normal": 3.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-22T14:23:46", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-23T00:01:17", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-23T02:53:10", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-23T10:26:09", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-23T12:45:53", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-23T19:04:33", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-24T02:03:30", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-24T08:42:05", "normal": 3.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-24T09:11:28", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-24T13:05:25", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-24T16:20:41", "normal": 0.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-24T19:39:24", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-24T22:58:57", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-25T09:05:32", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-25T09:15:49", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-25T10:05:32", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-25T15:20:46", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-26T00:34:00", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-26T00:40:32", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-26T17:42:21", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-27T00:26:46", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-27T01:56:53", "normal": 3.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-27T15:00:57", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-27T16:30:36", "normal": 0.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-28T00:07:24", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-28T04:04:35", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-28T11:06:58", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-28T12:05:56", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-28T17:32:14", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-28T22:51:31", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-29T09:24:11", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-29T11:48:49", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-31T17:35:53", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-01T22:39:45", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-01T23:11:22", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-02T05:32:22", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-02T13:53:59", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-02T15:01:02", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-03T11:47:19", "normal": 0.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-03T17:52:13", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-04T00:51:30", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-04T01:35:03", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-04T10:23:28", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-05T00:40:31", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-05T22:10:18", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-06T00:30:31", "duration": 9000000, "extended": 2.4, @@ -2272,187 +2274,187 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-06T11:27:46", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-06T12:24:47", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-06T21:00:06", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-06T21:26:09", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-06T22:30:08", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-07T01:20:24", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-07T15:08:42", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-07T17:35:21", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-08T00:40:52", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-08T04:05:56", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-08T04:08:07", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-08T20:24:34", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-08T21:17:19", "normal": 9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-09T03:41:21", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-09T03:43:00", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-09T15:27:27", "normal": 4.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-09T16:50:23", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-10T00:06:05", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-10T07:13:02", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-10T10:23:08", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-11T01:16:30", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-11T13:20:10", "normal": 1.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-11T17:04:18", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-11T19:38:24", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-11T20:40:19", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-11T22:22:57", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-11T23:03:25", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-12T10:31:15", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-12T10:47:00", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-12T17:15:24", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-12T22:52:54", "duration": 5400000, "extended": 3.6, @@ -2460,344 +2462,344 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-12T23:37:16", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-13T03:06:20", "expectedNormal": 2.4, "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-13T04:51:10", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-13T19:40:33", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-13T20:05:03", "normal": 0.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-14T17:20:11", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-14T17:56:34", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-15T01:56:38", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-15T17:29:22", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-16T09:23:19", "normal": 2.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-17T11:56:27", "normal": 0.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-18T00:34:51", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-18T04:32:23", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-18T12:15:36", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-18T12:56:37", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-18T20:43:52", "normal": 9.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-19T03:06:10", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-19T17:37:52", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-19T18:33:24", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-19T22:24:06", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-19T23:15:16", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-19T23:57:50", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-20T11:27:44", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-20T12:13:32", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-20T17:12:58", "normal": 7.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-20T23:25:38", "normal": 4.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-21T18:12:48", "normal": 4.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-21T23:02:43", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-22T05:11:08", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-22T12:46:46", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-22T18:44:55", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-22T23:47:30", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-23T15:22:30", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-24T01:28:13", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-24T04:50:59", "normal": 3.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-24T10:06:16", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-24T10:57:20", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-24T16:20:38", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-24T20:57:10", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-24T21:10:06", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-25T01:46:05", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-25T03:01:41", "normal": 1.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-25T12:45:34", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-25T16:35:50", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-25T16:43:09", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-26T14:50:38", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-26T23:18:20", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-27T19:10:37", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-27T19:56:05", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-27T20:05:22", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-27T20:33:26", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-01T11:06:45", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-01T13:38:00", "normal": 0.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-01T17:26:06", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-02T05:10:59", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-02T14:53:50", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-02T15:15:41", "duration": 7200000, "extended": 4, @@ -2805,453 +2807,453 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-02T17:55:24", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-02T21:27:07", "normal": 3.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-03T02:23:28", "normal": 3.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-03T07:55:24", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-03T13:31:37", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-03T17:33:40", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-04T01:00:34", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-04T09:51:54", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-04T13:59:53", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-04T14:53:15", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-04T17:26:51", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-04T19:38:13", "normal": 8.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-04T23:09:52", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-04T23:57:26", "normal": 1.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-05T03:09:50", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-05T14:54:46", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-05T18:29:31", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-06T00:34:35", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-06T01:21:36", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-06T06:12:45", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-06T19:38:19", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-07T08:26:18", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-07T10:24:27", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-07T16:59:43", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-07T22:10:21", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-07T23:47:40", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-08T00:47:32", "duration": 10800000, "extended": 1.65, "subType": "square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-08T17:20:24", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-08T23:16:45", "normal": 2.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-09T09:43:12", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-09T19:36:18", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-09T21:47:07", "normal": 11, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-09T22:28:29", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-10T00:56:27", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-10T05:18:33", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-10T10:09:03", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-10T19:08:41", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-10T19:30:42", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-10T21:00:08", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-10T21:11:26", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-11T00:12:25", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-11T03:50:32", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-11T09:48:55", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-11T17:56:25", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-11T21:45:42", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-11T23:48:21", "normal": 7.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-11T23:59:24", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-12T11:02:19", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-12T14:13:44", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-12T23:30:03", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-13T00:01:21", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-13T08:23:02", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-13T15:29:58", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-13T16:25:10", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-14T01:00:14", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-14T01:48:33", "duration": 7200000, "extended": 5, "subType": "square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-14T08:26:33", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-14T09:15:40", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-14T21:17:36", "normal": 5.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-14T21:36:42", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-15T01:00:44", "normal": 4.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-15T12:10:00", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-15T13:36:53", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-15T21:24:43", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-15T22:46:02", "normal": 10, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-16T19:49:33", "normal": 12.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-17T15:56:01", "normal": 3.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-18T10:02:04", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-18T15:29:15", "normal": 6.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-18T16:27:25", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-18T21:15:02", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-19T06:28:44", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-19T15:28:25", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-19T22:15:08", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-20T08:14:49", "duration": 3600000, "extended": 1.5, @@ -3259,679 +3261,679 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-20T12:02:19", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-20T13:19:06", "normal": 0.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-20T16:07:19", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-20T19:43:27", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-20T20:56:53", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-21T00:32:48", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-21T14:39:05", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-21T21:09:21", "normal": 12, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-21T22:14:04", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-22T03:19:52", "expectedNormal": 5.15, "normal": 0.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-22T03:20:35", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-22T10:57:48", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-22T16:15:49", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-22T23:32:14", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-23T03:44:48", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-23T10:03:49", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-23T12:03:21", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-23T12:08:31", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-23T17:28:19", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-23T18:10:06", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-23T22:45:10", "normal": 6.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-23T23:57:11", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-24T01:52:51", "normal": 6.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-24T04:04:20", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-24T10:09:10", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-24T15:22:15", "normal": 9.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-24T15:59:21", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-24T18:45:12", "normal": 5.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-25T03:44:15", "normal": 6.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-25T04:12:56", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-25T13:25:50", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-25T15:47:08", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-25T16:27:53", "normal": 1.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-25T17:26:51", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-26T01:03:51", "normal": 9.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-26T04:48:39", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-26T15:52:08", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-26T18:11:28", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-26T21:42:00", "normal": 4.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-26T23:21:43", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-27T13:11:38", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-27T13:27:58", "normal": 5.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-27T13:43:12", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-27T14:19:41", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-28T01:21:26", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-28T02:49:55", "normal": 2.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-28T12:09:39", "normal": 5.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-28T21:12:56", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-29T01:42:57", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-29T12:10:07", "normal": 8.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-29T20:29:43", "normal": 8.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-29T23:08:20", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-29T23:23:56", "expectedNormal": 2, "normal": 0.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-29T23:24:13", "expectedNormal": 3.8, "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-29T23:25:03", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-30T09:17:33", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-30T11:41:40", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-30T18:46:16", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-30T22:26:35", "normal": 7.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-31T09:34:04", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-31T11:02:09", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-31T18:03:31", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-01T13:35:12", "normal": 4.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-01T19:00:43", "expectedNormal": 5.5, "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-02T11:24:01", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-03T00:24:02", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-03T04:46:03", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-03T13:58:14", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-03T15:41:52", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-03T22:48:16", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-03T22:53:19", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-03T23:37:06", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-04T17:49:44", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-04T18:25:58", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-04T20:06:51", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-04T20:50:31", "expectedNormal": 6.5, "normal": 4.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-04T21:47:42", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-05T11:10:22", "normal": 8.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-05T13:57:52", "normal": 5.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-05T14:41:02", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-05T19:55:35", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-05T20:07:23", "normal": 6.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-05T23:10:52", "normal": 10.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-06T17:04:13", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-07T00:30:35", "normal": 13, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-07T11:30:23", "expectedNormal": 11.3, "normal": 7.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-07T13:39:36", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-07T15:31:20", "normal": 7.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-07T17:03:27", "normal": 6.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-07T19:36:38", "normal": 11.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T02:04:38", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T11:36:22", "normal": 4.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T15:35:43", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T16:36:54", "normal": 4.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T17:06:19", "normal": 2.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T18:36:43", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T20:45:53", "normal": 9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T21:43:56", "normal": 5.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T22:27:26", "normal": 8.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-09T13:34:32", "normal": 4.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-09T23:51:42", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-10T11:33:52", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-10T15:06:31", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-10T16:39:01", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-10T23:28:10", "normal": 2.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-10T23:56:06", "normal": 3.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-11T08:31:34", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-11T14:14:04", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-11T21:33:10", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-12T13:11:06", "normal": 5.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-12T15:22:32", "normal": 1.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-12T20:37:48", "duration": 3600000, "extended": 1.4, @@ -3939,37 +3941,37 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-13T07:00:52", "normal": 2.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-13T11:55:34", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-13T15:38:33", "normal": 5.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-13T16:43:21", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-13T22:25:40", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-13T23:43:31", "duration": 3600000, "extended": 3, @@ -3977,556 +3979,556 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-14T07:24:30", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-14T11:26:07", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-14T14:02:33", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-14T16:13:29", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-14T16:21:37", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-15T04:30:42", "normal": 2.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-15T11:27:28", "normal": 9.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-15T21:09:40", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-15T21:29:47", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-16T08:42:28", "normal": 3.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-16T09:08:02", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-16T18:50:11", "normal": 7.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-16T22:19:29", "normal": 8.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-17T07:49:58", "expectedNormal": 6.25, "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-17T10:22:10", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-17T15:38:57", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-17T16:53:15", "normal": 4.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-17T23:01:44", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-17T23:17:46", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-18T03:36:54", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-18T08:15:40", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-18T13:03:08", "normal": 6.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-18T22:49:11", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-19T10:49:57", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-19T12:47:07", "normal": 7.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-19T18:51:49", "normal": 0.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T00:34:12", "normal": 4.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T11:55:56", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T12:21:25", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T12:25:59", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T12:40:44", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T16:51:52", "normal": 5.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T17:13:53", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T18:53:57", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T21:13:02", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T21:17:28", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T22:56:20", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-21T05:00:30", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-21T14:57:12", "expectedNormal": 5.7, "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-21T17:25:57", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-21T19:55:14", "normal": 5.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-21T20:21:02", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-21T20:48:12", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-21T23:36:01", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-22T00:17:02", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-22T07:20:00", "normal": 3.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-22T09:32:51", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-22T15:34:54", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-22T17:17:07", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-22T18:33:33", "normal": 8.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-22T19:56:36", "normal": 4.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-22T21:38:22", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-23T14:44:27", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-23T16:39:55", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-23T17:17:36", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-23T18:45:04", "normal": 2.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-23T21:54:57", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-23T23:08:34", "expectedNormal": 2.5, "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-23T23:30:54", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-24T10:55:10", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-24T16:10:07", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-24T18:45:06", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-24T21:29:29", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-25T02:05:38", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-25T16:31:35", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-25T16:52:59", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-25T23:23:29", "normal": 9.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-26T10:15:03", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-26T13:15:18", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-26T13:53:04", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-26T15:43:54", "normal": 4.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-26T20:06:36", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-27T12:42:46", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-27T15:48:19", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-27T15:53:18", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-27T23:14:39", "normal": 9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-28T02:49:38", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-28T14:15:39", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-28T15:36:19", "normal": 3.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-28T17:22:40", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-28T23:33:46", "normal": 6.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-29T12:43:56", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-29T14:24:57", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-29T16:00:35", "normal": 0.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-29T22:51:00", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-30T16:41:59", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-30T23:51:20", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-01T00:40:06", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-01T02:19:29", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-01T15:47:28", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-01T17:58:20", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-02T01:01:32", "duration": 5400000, "extended": 1.85, @@ -4534,649 +4536,649 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-02T14:35:54", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-02T16:30:55", "normal": 1.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-02T18:03:13", "normal": 2.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-02T18:30:32", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-02T22:44:03", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-03T13:28:40", "normal": 7.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-03T22:38:40", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-04T06:40:11", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-04T12:09:02", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-04T12:42:38", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-04T13:58:04", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-04T19:31:20", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-05T13:12:58", "normal": 5.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-05T17:02:00", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-05T22:18:24", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-06T12:34:16", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-06T20:28:21", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-06T21:05:28", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-07T10:11:40", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-07T12:47:09", "normal": 4.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-07T20:59:51", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-07T21:46:06", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-08T07:29:03", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-08T13:44:00", "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-08T20:00:38", "normal": 2.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-09T14:28:06", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-09T23:50:14", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-10T10:13:12", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-10T12:28:54", "normal": 2.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-10T14:38:18", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-10T18:48:40", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-10T19:22:11", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-10T20:10:02", "normal": 0.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-10T20:43:41", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-11T02:11:06", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-11T15:22:52", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-11T19:51:32", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-11T20:01:17", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-11T21:07:27", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-11T22:40:53", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-12T00:51:28", "normal": 5.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-12T09:31:50", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-12T17:24:32", "normal": 4.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-12T17:31:58", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-12T19:20:54", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-12T20:09:19", "normal": 6.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-12T23:53:39", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-13T06:04:08", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-13T09:33:30", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-13T10:02:35", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-13T13:25:22", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-13T14:39:05", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-13T21:27:31", "normal": 5.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-13T21:49:54", "normal": 4.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-14T06:30:45", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-14T17:13:50", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-14T19:51:30", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-15T02:59:12", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-15T18:34:17", "normal": 8.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-15T20:03:48", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-15T20:13:10", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-15T21:08:56", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-15T21:38:31", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-16T11:44:10", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-16T13:54:41", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-16T17:33:07", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-16T18:59:52", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-16T22:40:06", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-17T10:47:43", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-17T17:33:07", "normal": 1.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-17T21:09:30", "normal": 8.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-17T21:38:23", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-18T14:40:29", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-18T16:20:15", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-18T17:18:29", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-18T21:04:49", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-19T08:29:53", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-19T10:55:07", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-19T13:03:51", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-19T20:15:44", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-19T20:28:37", "normal": 10.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-20T00:18:39", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-20T01:24:17", "normal": 0.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-20T07:49:45", "normal": 0.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-20T11:51:55", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-20T12:13:22", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-20T14:57:44", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-20T18:03:00", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-21T10:31:41", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-21T13:57:19", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-21T19:23:59", "normal": 10, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-21T22:46:23", "normal": 3.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-22T09:51:09", "normal": 9.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-22T19:41:23", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-22T22:49:19", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-23T07:43:22", "normal": 5.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-23T15:05:51", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-23T16:43:30", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-23T20:24:21", "normal": 10.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-23T20:36:41", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-24T01:31:04", "normal": 3.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-24T12:17:15", "normal": 4.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-24T13:52:54", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-24T22:00:26", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-24T22:31:42", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-25T07:08:36", "normal": 3.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-25T09:25:26", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-25T10:43:07", "duration": 3600000, "extended": 2.15, @@ -5184,482 +5186,482 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-25T15:29:54", "normal": 5.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-25T19:28:58", "normal": 4.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-25T21:48:56", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-26T07:47:05", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-26T15:09:57", "normal": 3.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-26T15:23:19", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-26T19:21:32", "normal": 3.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-26T22:54:32", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-27T08:07:50", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-27T12:47:09", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-27T13:23:20", "normal": 1.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-27T17:55:40", "normal": 7.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-27T19:30:40", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-27T22:57:00", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-28T02:25:19", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-28T16:54:27", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-28T17:18:04", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-28T19:15:15", "normal": 6.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-28T20:51:16", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-28T23:10:50", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-29T01:18:06", "normal": 1.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-29T14:47:42", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-29T16:34:10", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-29T22:26:32", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-31T04:03:49", "normal": 4.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-31T10:56:21", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-31T13:27:12", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-31T19:41:58", "normal": 2.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-31T21:08:12", "normal": 5.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-31T22:40:45", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-31T23:11:40", "normal": 5.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-01T11:33:30", "normal": 2.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-01T20:49:42", "normal": 5.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-01T23:31:41", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-02T02:42:26", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-02T03:08:32", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-02T12:36:04", "normal": 7.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-02T13:23:44", "normal": 4.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-02T20:07:26", "normal": 7.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-03T15:01:33", "normal": 0.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-03T15:46:39", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-03T16:41:33", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-03T17:18:38", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-03T17:43:38", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-04T10:16:53", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-04T14:50:00", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-04T16:14:19", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-04T19:21:41", "normal": 8.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-04T23:46:41", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-05T00:44:34", "expectedNormal": 2, "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-05T01:02:58", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-05T12:01:09", "normal": 2.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-05T12:23:18", "normal": 0.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-05T12:51:54", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-05T15:39:48", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-05T21:29:36", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-06T04:21:34", "normal": 2.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-06T08:53:58", "normal": 1.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-07T15:08:48", "normal": 0.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-10T19:54:26", "normal": 7.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-08T15:53:04", "normal": 5.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-08T22:22:31", "normal": 7.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-08T22:47:20", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-09T15:51:36", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-10T00:59:27", "normal": 1.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-10T10:23:36", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-10T18:30:44", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-10T18:39:41", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-10T19:47:34", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-11T13:53:18", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-11T20:58:05", "normal": 10, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-12T00:35:54", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-12T13:04:51", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-12T17:37:35", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-12T19:09:48", "normal": 1.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-12T19:34:40", "normal": 0.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-13T00:02:43", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-13T00:11:41", "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-13T08:33:39", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-13T20:19:52", "duration": 1800000, "extended": 2.55, @@ -5667,97 +5669,97 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-14T16:44:31", "normal": 8.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-14T22:46:55", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-15T00:28:57", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-15T08:51:33", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-15T11:33:53", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-15T19:09:51", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-16T17:02:11", "normal": 3.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-16T18:49:50", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-16T20:22:02", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-17T11:14:04", "normal": 0.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-17T19:29:27", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-18T06:45:25", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-18T15:28:35", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-18T16:20:17", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-18T16:50:44", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-18T22:16:57", "duration": 3600000, "extended": 4.2, @@ -5765,31 +5767,31 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-19T07:18:23", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-19T18:51:48", "normal": 4.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-20T08:50:29", "normal": 0.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-20T11:19:38", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-20T15:42:53", "duration": 1800000, "extended": 0.45, @@ -5797,7 +5799,7 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-20T17:25:24", "duration": 3600000, "extended": 0.75, @@ -5805,7 +5807,7 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-20T21:38:30", "duration": 3600000, "extended": 2.85, @@ -5813,7 +5815,7 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-21T11:54:08", "duration": 3600000, "extended": 2.8, @@ -5821,55 +5823,55 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-21T14:39:04", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-21T18:23:31", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-21T19:29:16", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-21T20:00:12", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-21T21:40:40", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-21T23:42:55", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-22T00:24:30", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-22T08:20:59", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-22T21:37:44", "duration": 3600000, "extended": 1.2, @@ -5877,31 +5879,31 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-22T22:25:47", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-22T23:37:05", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-23T07:32:39", "normal": 1.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-23T19:09:07", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-23T20:27:18", "duration": 3600000, "extended": 1.75, @@ -5909,314 +5911,314 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-23T22:28:35", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-23T23:23:04", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T08:19:28", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T09:04:06", "normal": 1.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T10:00:56", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T18:30:46", "normal": 4.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T19:44:10", "normal": 1.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T20:32:30", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T20:39:38", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-25T09:17:23", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-25T16:59:11", "normal": 3.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-25T17:49:12", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-25T19:55:43", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-26T03:01:17", "normal": 1.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-26T07:05:35", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-26T09:44:50", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-27T16:48:06", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-27T17:13:45", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-27T17:57:18", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-27T22:06:32", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-28T15:46:44", "normal": 6.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-28T16:18:13", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-28T16:23:18", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-28T16:28:41", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-29T18:27:23", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-30T12:43:51", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-01T17:46:55", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-01T18:30:32", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-01T18:51:38", "normal": 4.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-02T00:15:19", "normal": 4.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-02T06:49:58", "normal": 1.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-02T18:35:00", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-03T12:03:51", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-03T12:50:24", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-03T17:08:12", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-03T17:41:00", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-03T19:08:04", "expectedNormal": 2, "normal": 0.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-03T19:08:18", "normal": 0.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-04T01:21:22", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-04T14:10:31", "normal": 1.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-04T17:59:30", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-04T19:21:37", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-04T19:25:51", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-04T20:09:01", "normal": 7.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-05T02:02:39", "normal": 1.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-05T02:36:40", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-05T13:58:30", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-05T17:17:54", "normal": 6.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-05T23:40:50", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-06T01:28:33", "normal": 3.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-06T14:59:11", "normal": 2.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-06T20:26:50", "duration": 3600000, "extended": 2, @@ -6224,19 +6226,19 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-07T00:48:50", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-07T14:09:43", "normal": 3.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-07T16:02:12", "duration": 5400000, "extended": 3.25, @@ -6244,37 +6246,37 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-08T18:17:26", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-08T18:29:06", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-08T20:29:43", "normal": 5.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-08T23:53:16", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-09T12:19:24", "normal": 5.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-09T16:27:30", "duration": 3600000, "extended": 1, @@ -6282,271 +6284,271 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-09T17:50:34", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-10T00:25:49", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-10T17:43:21", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-10T18:08:03", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-11T13:06:32", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-11T19:37:52", "normal": 7.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-12T00:07:01", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-12T00:42:51", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-12T07:40:06", "normal": 3.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-12T08:50:10", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-12T16:09:42", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-12T21:45:57", "normal": 6.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-13T10:56:43", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-13T11:42:47", "normal": 1.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-13T16:33:50", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-13T18:21:41", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-13T22:13:37", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-13T22:19:30", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-13T22:48:14", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-13T23:08:30", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-14T14:31:41", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-14T15:53:20", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-14T17:37:39", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-14T18:15:11", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-14T20:29:30", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-15T12:18:56", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-15T14:09:52", "normal": 4.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-15T17:23:04", "normal": 2.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-15T21:15:01", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-15T21:44:35", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-15T22:12:37", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-15T22:57:20", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-15T22:58:49", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-16T09:35:57", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-16T11:31:07", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-16T15:12:49", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-16T15:41:21", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-16T21:04:38", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-17T03:22:39", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-17T14:09:57", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-17T16:29:43", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-18T05:26:35", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-18T08:03:17", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-18T17:58:39", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-18T20:40:22", "duration": 1800000, "extended": 5.7, @@ -6554,43 +6556,43 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-19T08:36:08", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-19T15:20:39", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-19T18:22:28", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-19T18:54:15", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-19T22:20:06", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-19T22:47:22", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-20T14:23:03", "duration": 3600000, "extended": 1.35, @@ -6598,67 +6600,67 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-20T15:02:15", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-20T15:50:21", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-21T00:08:35", "normal": 1.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-21T12:12:24", "normal": 5.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-21T15:13:53", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-22T16:11:14", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-23T01:06:51", "normal": 2.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-23T10:37:02", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-23T16:18:09", "normal": 6.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-23T16:57:31", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-23T21:30:01", "duration": 1800000, "extended": 3.55, @@ -6666,163 +6668,163 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-24T08:03:19", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-24T13:21:49", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-24T13:41:26", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-24T15:13:42", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-24T17:30:34", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-24T18:47:01", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-25T00:37:32", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-25T15:27:34", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-25T15:50:46", "normal": 6.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-25T18:34:45", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-26T08:00:02", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-26T15:30:21", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-26T16:43:37", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-26T22:55:06", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-27T00:34:23", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-27T16:08:38", "normal": 5.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-28T10:22:34", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-28T10:42:12", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-28T11:14:05", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-28T12:22:02", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-28T17:58:24", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-29T00:59:10", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-29T13:21:48", "normal": 3.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-29T14:26:37", "normal": 5.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-29T15:29:23", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-29T19:11:00", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-29T21:59:18", "duration": 10800000, "extended": 8.65, @@ -6830,31 +6832,31 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-30T07:29:04", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-30T11:32:41", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-30T13:33:42", "normal": 2.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-30T15:10:57", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-30T16:48:04", "duration": 2700000, "expectedDuration": 3600000, @@ -6864,212 +6866,212 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-30T17:35:25", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-31T06:01:14", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-31T08:02:24", "expectedNormal": 1.8, "normal": 0, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-31T17:32:27", "normal": 2.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-31T19:24:54", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-31T20:15:14", "normal": 7.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-31T23:11:02", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-01T15:38:03", "normal": 7.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-02T00:53:24", "normal": 1.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-02T09:42:56", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-02T12:33:40", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-03T13:13:56", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-03T13:30:33", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-03T19:02:46", "normal": 7.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-03T23:23:36", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-03T23:30:48", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-04T07:57:10", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-04T17:05:51", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-04T18:14:03", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-05T16:45:27", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-05T19:47:08", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-06T09:25:42", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-06T15:20:44", "normal": 5.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-06T16:19:31", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-06T17:07:49", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-06T19:58:23", "normal": 7.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-07T14:38:43", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-07T19:47:20", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-07T20:51:30", "normal": 8.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-07T21:31:38", "normal": 5.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-08T01:05:38", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-08T10:11:09", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-08T15:43:17", "normal": 6.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-08T19:52:56", "normal": 0.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-08T20:57:40", "duration": 3600000, "extended": 2, @@ -7077,568 +7079,568 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-09T09:07:47", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-09T16:17:45", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-09T17:24:45", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-11T01:12:55", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-11T18:24:34", "normal": 5.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-11T19:04:48", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-11T20:30:46", "normal": 0.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-12T10:04:06", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-13T17:30:51", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-13T18:15:01", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-13T18:43:29", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-14T15:37:44", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-15T01:47:54", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-15T13:59:56", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-15T14:41:43", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-15T14:44:38", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-15T21:54:18", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-16T15:51:57", "normal": 7.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-16T16:23:22", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-16T20:59:44", "normal": 7.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-16T22:28:09", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-17T13:43:39", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-17T15:22:58", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-17T20:43:00", "normal": 4.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-17T22:37:07", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-18T12:51:55", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-18T15:37:39", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-18T16:20:47", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-18T16:23:34", "expectedNormal": 1, "normal": 0, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-18T16:23:47", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-19T01:18:52", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-19T18:35:04", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-19T18:45:16", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-19T19:19:18", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-19T19:49:49", "normal": 9.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-20T13:23:57", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-20T18:56:03", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-21T18:29:04", "normal": 8.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-21T20:46:21", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-22T21:10:05", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-22T21:58:04", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-22T22:02:55", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-23T18:27:37", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-23T20:31:41", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-23T20:59:54", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-23T23:21:11", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-24T10:24:29", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-24T17:07:32", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-24T17:33:08", "normal": 0.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-24T18:35:51", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-25T14:07:13", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-25T17:12:17", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-25T21:24:58", "normal": 8.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-26T11:35:34", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-26T11:48:12", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-26T12:08:19", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-26T16:13:11", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-26T22:12:41", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-27T01:27:13", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-27T16:56:37", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-27T19:56:41", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-27T20:22:28", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-27T20:57:07", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-28T07:42:06", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-28T09:05:30", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-28T09:54:05", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-28T14:01:25", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-28T15:50:43", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-28T20:59:49", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-28T21:29:58", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-29T01:28:07", "expectedNormal": 3, "normal": 0, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-29T01:28:23", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-29T05:09:40", "expectedNormal": 2.55, "normal": 1.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-29T05:18:26", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-29T06:58:48", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-29T07:02:43", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-29T13:23:14", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-29T21:18:42", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-30T15:27:04", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-30T15:45:46", "normal": 5.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-30T16:03:48", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-30T21:27:24", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-31T00:32:49", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-31T14:12:55", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-01T00:10:43", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-01T00:20:00", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-01T01:11:31", "normal": 5.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-01T18:11:06", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-01T18:59:49", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-01T23:21:40", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T01:17:05", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T07:22:03", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T09:19:07", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T15:32:12", "duration": 3600000, "extended": 1.65, @@ -7646,385 +7648,385 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T17:09:29", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T19:39:58", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T20:38:24", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T20:44:02", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T21:40:20", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-03T00:20:40", "normal": 3.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-03T06:42:57", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-03T14:08:27", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-03T14:48:55", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-03T17:14:46", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-03T22:34:31", "normal": 5.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-04T00:28:34", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-04T06:09:22", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-04T14:45:39", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-04T18:24:53", "normal": 10.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-05T01:06:54", "normal": 6.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-05T16:22:33", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-05T16:58:48", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-05T21:45:50", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-06T00:55:25", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-06T15:41:42", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-06T15:45:31", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-06T16:47:53", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-06T21:15:40", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-07T19:12:03", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-07T19:57:42", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-07T20:27:57", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-07T23:09:54", "normal": 10.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-08T06:49:54", "normal": 5.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-08T13:38:14", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-08T19:03:48", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-08T21:12:03", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-08T22:21:55", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-09T01:19:46", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-09T15:05:45", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-09T22:54:59", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-09T23:26:51", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-10T16:45:44", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-10T17:22:05", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-10T20:02:24", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-10T22:48:01", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-10T23:18:10", "normal": 4.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-11T17:11:53", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-11T23:15:24", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-12T00:04:13", "normal": 2.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-12T00:28:22", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-12T15:21:56", "normal": 4.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-13T15:59:02", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-13T22:06:29", "normal": 6.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-14T11:11:32", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-14T13:09:35", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-14T19:24:39", "normal": 10.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-15T15:36:19", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-15T21:46:47", "normal": 5.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-15T22:10:16", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-16T15:44:33", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-16T21:36:53", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-17T15:59:12", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-17T16:08:56", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-17T21:09:25", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-18T09:37:49", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-18T18:20:54", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-18T18:51:09", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-19T13:27:26", "duration": 3600000, "extended": 0.55, @@ -8032,1131 +8034,1131 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-19T14:53:40", "normal": 4.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-19T15:24:30", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-20T18:32:41", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-20T21:29:36", "normal": 5.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-21T15:35:49", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-21T21:03:52", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-21T22:39:49", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-22T11:25:56", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-22T13:19:40", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-22T17:25:35", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-22T19:59:31", "normal": 2.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-22T22:50:19", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-23T11:45:40", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-23T11:47:49", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-23T12:07:32", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-23T15:08:45", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-23T20:33:01", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-23T22:00:40", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-24T06:08:59", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-24T08:33:59", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-24T11:22:33", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-24T21:52:26", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-24T22:08:46", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-25T16:52:46", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-25T20:23:33", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-25T20:36:44", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-26T07:18:20", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-26T10:15:04", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-26T16:11:43", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-26T19:25:09", "normal": 6.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-26T21:22:26", "normal": 1.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-27T12:14:07", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-27T13:57:02", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-27T14:09:20", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-27T15:29:54", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-27T20:48:41", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-27T21:12:09", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-27T21:20:49", "normal": 7.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-27T21:49:25", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-28T04:50:11", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-28T07:40:45", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-28T12:06:19", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-28T15:46:19", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-28T21:47:01", "normal": 12.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-29T01:12:35", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-29T02:08:17", "normal": 2.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-29T02:59:26", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-29T14:42:33", "normal": 7.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-29T15:02:43", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-29T15:12:10", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-29T19:10:18", "normal": 5.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-29T19:46:49", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-30T11:29:40", "normal": 10, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-30T13:56:15", "normal": 5.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-30T15:42:59", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-30T22:53:22", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-30T23:05:22", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-30T23:35:16", "normal": 7.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-01T14:27:43", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-01T16:04:42", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-01T22:28:45", "normal": 6.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-02T17:01:12", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-02T18:18:32", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-02T22:08:17", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-02T22:56:37", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-03T07:44:00", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-03T08:42:58", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-03T15:24:28", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-03T17:53:59", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-03T19:00:37", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-03T22:17:33", "normal": 7.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-04T09:52:11", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-04T12:55:58", "normal": 2.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-04T15:12:11", "normal": 6.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-04T20:09:22", "normal": 3.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-05T03:27:19", "normal": 4.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-05T19:22:47", "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-05T22:39:45", "normal": 10.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-06T06:12:37", "normal": 4.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-06T12:42:06", "normal": 8.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-06T15:32:00", "expectedNormal": 4.7, "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-06T19:07:20", "normal": 4.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-06T19:39:58", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-07T00:20:47", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-07T05:30:49", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-07T08:21:15", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-07T22:44:14", "normal": 8.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-08T06:58:25", "normal": 4.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-08T08:16:59", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-08T13:52:10", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-08T19:52:08", "normal": 5.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-09T06:26:22", "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-09T07:43:04", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-09T15:08:46", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-09T15:54:44", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-09T23:03:47", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-09T23:38:04", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-10T16:02:43", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-10T22:56:35", "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-10T23:35:59", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-11T15:03:25", "normal": 3.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-11T16:13:04", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-11T21:19:03", "normal": 7.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-12T07:22:58", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-12T15:16:54", "normal": 3.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-12T15:54:25", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-12T21:11:04", "normal": 4.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-13T13:15:55", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-13T13:18:43", "normal": 5.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-13T16:26:19", "normal": 6.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-13T20:33:47", "normal": 8.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-13T20:49:06", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-13T21:24:48", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-13T23:18:40", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-13T23:45:17", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-14T00:25:53", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-14T01:10:52", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-14T12:00:00", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-14T15:36:08", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-14T16:01:10", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-14T19:58:59", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-14T20:51:48", "normal": 8.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-14T21:40:26", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-14T23:14:13", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-15T00:33:52", "normal": 3.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-15T08:45:17", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-15T15:49:05", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-15T21:53:25", "normal": 8.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-15T22:38:18", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-16T16:47:33", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-16T22:22:47", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-16T23:27:48", "normal": 14.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-17T15:50:12", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-17T15:52:31", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-18T14:12:19", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-18T15:09:54", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-18T15:27:12", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-18T15:57:46", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-18T23:28:05", "normal": 8.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-19T00:10:14", "normal": 5.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-19T00:46:24", "normal": 5.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-19T01:11:02", "normal": 5.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-19T14:59:14", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-19T16:28:00", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-19T22:00:22", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-19T23:24:34", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-20T17:39:33", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-20T19:27:43", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-20T20:07:49", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-20T20:43:12", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-20T21:54:33", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-21T14:16:42", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-21T20:42:35", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-22T12:14:12", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-23T07:12:15", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-23T11:12:32", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-23T12:36:16", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-23T12:50:53", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-23T14:17:09", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-24T10:47:06", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-24T14:20:06", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-24T16:11:40", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-25T00:18:43", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-25T19:12:42", "normal": 3.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-25T20:42:26", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-26T18:49:01", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-27T18:11:11", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-27T20:47:51", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-28T13:28:57", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-28T13:31:35", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-28T13:43:39", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-28T18:08:08", "normal": 2.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-29T03:56:45", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-29T15:09:37", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-29T15:58:27", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-30T02:57:09", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-30T16:34:05", "normal": 10, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-30T19:17:07", "expectedNormal": 8, "normal": 6.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-30T23:28:05", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-31T20:19:12", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-01T16:10:05", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-01T23:01:05", "normal": 3.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-02T17:16:10", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-02T23:46:20", "normal": 8.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-03T12:56:37", "normal": 6.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-03T13:09:30", "normal": 7.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-03T16:07:02", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-03T20:10:25", "duration": 3600000, "extended": 2.2, @@ -9164,37 +9166,37 @@ var JFBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-04T05:00:38", "normal": 3.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-04T12:35:17", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-04T15:46:38", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-04T22:01:14", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-05T09:37:58", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-05T13:19:18", "normal": 2, "subType": "normal", @@ -9203,1002 +9205,1002 @@ var JFBolusSet = []map[string]interface{}{ var PlatformBolusSet = []map[string]interface{}{ { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-11T05:48:32", "normal": 1.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-11T05:48:32", "normal": 1.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-11T08:48:43", "normal": 2.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-11T08:48:43", "normal": 2.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-11T17:07:35", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-11T17:48:17", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-11T22:16:32", "expectedNormal": 6, "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T02:48:01", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T02:57:56", "normal": 2.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T02:57:56", "normal": 2.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T03:45:23", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T04:02:33", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T04:02:33", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T04:07:54", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T12:10:52", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T12:10:52", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T13:43:31", "normal": 0.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T13:43:31", "normal": 0.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T18:55:53", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-12T22:06:00", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-13T00:07:54", "normal": 6.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-13T15:36:15", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-13T15:36:15", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-13T19:15:32", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-13T23:32:46", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-14T02:56:18", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-14T15:05:16", "normal": 5.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-14T15:05:16", "normal": 5.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-14T18:45:59", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-14T21:06:30", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-15T02:10:44", "expectedNormal": 6, "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-15T10:11:52", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-15T10:21:08", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-15T10:52:13", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-15T18:51:32", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-15T20:32:07", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-15T20:43:33", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-15T20:43:33", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-15T21:26:55", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-16T07:56:57", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-16T07:56:57", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-16T15:32:09", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-16T15:32:09", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-16T16:04:19", "expectedNormal": 3.7, "normal": 0.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-16T16:04:45", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-16T16:23:41", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-16T16:35:34", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-16T16:58:46", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-16T22:04:48", "normal": 4.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T07:49:22", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T07:49:22", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T07:58:22", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T08:31:44", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T09:25:59", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T15:19:35", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T15:41:16", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T16:13:32", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T16:51:39", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T17:36:34", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-17T22:24:30", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-18T00:26:16", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-18T00:57:05", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-18T09:39:10", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-18T13:26:16", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-18T15:56:31", "normal": 0.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-18T15:56:31", "normal": 0.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-18T16:46:24", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-18T17:16:59", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-18T17:16:59", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-19T01:21:09", "normal": 2.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-19T01:21:09", "normal": 2.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-19T01:51:44", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-19T18:01:16", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-19T19:01:35", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-19T22:24:42", "normal": 3.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-19T22:27:54", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-19T23:16:39", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-20T11:50:37", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-20T13:36:40", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-20T13:36:40", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-20T18:31:12", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-20T19:04:49", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-20T19:13:53", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-21T14:16:39", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-22T00:12:03", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-22T00:12:03", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-22T13:54:39", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-22T20:02:33", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-22T20:09:02", "normal": 7.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-22T20:42:46", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-22T20:51:20", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-23T14:51:38", "normal": 5.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-23T14:51:38", "normal": 5.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-23T17:40:56", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-24T10:57:40", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-24T13:49:15", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-24T13:49:15", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-24T20:29:08", "normal": 5.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-24T20:29:08", "normal": 5.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-24T23:20:14", "normal": 2.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-24T23:20:14", "normal": 2.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T02:11:25", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T02:11:25", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T03:41:15", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T03:49:26", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T11:34:54", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T11:36:30", "expectedNormal": 3.7, "normal": 2.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T11:39:54", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T18:55:44", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T21:00:32", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T21:56:23", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-25T22:40:16", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-26T00:47:19", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-26T11:19:24", "normal": 6.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-26T11:19:24", "normal": 6.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-26T18:22:46", "normal": 9.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-26T18:22:46", "normal": 9.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-26T20:06:31", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-26T21:00:39", "normal": 4.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-27T00:43:11", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-27T00:54:23", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-27T01:21:34", "normal": 0.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-27T01:21:34", "normal": 0.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-27T07:02:47", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-27T08:20:19", "normal": 3.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-27T08:20:19", "normal": 3.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-27T11:57:25", "normal": 9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-27T18:36:04", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-27T20:18:11", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-28T10:55:51", "normal": 10.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-28T13:31:27", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-28T17:47:15", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-28T18:58:25", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-28T20:20:09", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T05:47:36", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T11:04:51", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T11:17:10", "expectedNormal": 5, "normal": 0.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T11:17:44", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T11:59:21", "normal": 4.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T11:59:21", "normal": 4.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T12:33:05", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T16:04:51", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T18:22:02", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T18:22:02", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-29T20:35:15", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-30T00:19:10", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-30T01:14:53", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-30T11:38:04", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-30T11:38:04", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-30T14:10:30", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-30T18:11:40", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-30T19:40:37", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-11-30T22:39:58", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-01T09:55:37", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-01T12:02:23", "normal": 4.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-01T12:02:23", "normal": 4.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-01T12:11:07", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-01T15:03:11", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-01T23:36:08", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-02T13:42:27", "normal": 2.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-02T13:42:27", "normal": 2.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-03T08:36:32", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-03T12:46:16", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-03T14:31:00", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-03T19:01:03", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-03T19:13:12", "duration": 3600000, "extended": 1.35, @@ -10206,7 +10208,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-03T19:13:12", "duration": 3600000, "extended": 1.35, @@ -10214,1807 +10216,1807 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-03T23:09:17", "expectedNormal": 5.6, "normal": 4.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-03T23:09:17", "expectedNormal": 5.6, "normal": 4.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-04T01:32:34", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-04T13:31:48", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-04T23:45:20", "normal": 5.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-05T05:38:22", "normal": 4.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-05T05:38:22", "normal": 4.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-05T13:05:36", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-05T18:04:44", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-05T22:31:49", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-06T09:05:49", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-06T19:44:34", "normal": 3.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-06T19:44:34", "normal": 3.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-07T11:30:47", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-07T17:39:58", "normal": 3.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-08T09:36:46", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-08T09:36:46", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-08T12:09:06", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-08T13:51:33", "normal": 1.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-08T13:51:33", "normal": 1.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-08T22:47:22", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-08T23:06:37", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-08T23:34:05", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-09T11:51:03", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-09T18:28:48", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-09T18:41:43", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-09T19:46:42", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-09T19:46:42", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-09T22:41:34", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-10T03:05:28", "normal": 1.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-10T03:05:28", "normal": 1.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-10T11:34:38", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-10T14:55:50", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-10T15:23:08", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-10T19:28:56", "normal": 8.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-10T21:16:11", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-10T22:17:25", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-11T14:30:42", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-11T19:17:18", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-12T13:15:43", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-12T14:37:19", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-12T20:45:23", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-12T21:17:50", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-12T22:07:50", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-12T23:57:33", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-12T23:57:33", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-13T10:28:04", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-13T10:28:04", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-13T17:42:12", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-14T04:31:16", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-14T09:40:01", "normal": 3.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-14T09:40:01", "normal": 3.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-14T15:57:40", "normal": 2.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-14T15:57:40", "normal": 2.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-14T17:26:58", "normal": 2.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-14T17:26:58", "normal": 2.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-15T05:49:43", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-15T09:42:54", "normal": 2.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-15T09:42:54", "normal": 2.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-15T15:42:11", "normal": 4.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-15T17:58:05", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-15T20:36:40", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-15T21:54:57", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-16T02:10:54", "normal": 5.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-16T05:18:35", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-16T05:18:35", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-16T17:03:43", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-16T21:17:40", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-16T21:27:12", "expectedNormal": 1.8, "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-17T15:02:37", "normal": 5.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-17T15:02:37", "normal": 5.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-18T08:53:51", "normal": 3.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-18T08:53:51", "normal": 3.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-18T14:07:21", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-18T14:07:21", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-19T00:37:12", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-20T22:52:22", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-20T22:52:22", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-21T16:04:44", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-21T16:04:44", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-21T17:31:36", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-22T20:34:13", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T00:32:29", "normal": 3.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T00:32:29", "normal": 3.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T02:01:53", "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T02:01:53", "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T13:25:12", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T14:45:29", "normal": 5.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T14:45:29", "normal": 5.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T15:17:41", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T15:27:27", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T20:51:42", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T20:51:42", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T22:28:05", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-23T22:28:05", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-24T15:45:49", "normal": 5.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-24T15:45:49", "normal": 5.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-24T17:30:54", "normal": 5.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-25T03:24:31", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-25T17:51:24", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-25T18:17:02", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-25T18:44:42", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-25T19:06:09", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-26T04:38:05", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-26T21:52:20", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-26T22:10:35", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-27T00:35:55", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-27T12:09:08", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-27T13:12:31", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-27T22:06:04", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-27T23:57:59", "normal": 8.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-27T23:57:59", "normal": 8.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-28T13:41:05", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-28T13:41:05", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-28T21:53:48", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-28T21:53:48", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-28T22:38:58", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-28T23:35:34", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-29T01:10:10", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-29T13:28:49", "normal": 7.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-29T15:31:09", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-29T15:47:25", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-29T20:49:26", "normal": 10.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-29T20:49:26", "normal": 10.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-29T23:31:22", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T01:14:51", "normal": 2.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T01:14:51", "normal": 2.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T10:07:54", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T14:41:41", "normal": 3.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T14:41:41", "normal": 3.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T15:36:28", "normal": 0.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T15:36:28", "normal": 0.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T17:21:07", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T17:47:07", "normal": 1.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T17:47:07", "normal": 1.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T19:43:22", "normal": 10.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T21:42:19", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T23:34:45", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-30T23:57:13", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-31T14:15:24", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-31T15:37:20", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-31T16:37:23", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-31T20:22:35", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2017-12-31T22:50:28", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-01T00:18:37", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-01T03:28:56", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-01T08:23:20", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-01T17:09:58", "normal": 5.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-01T17:09:58", "normal": 5.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-01T20:29:55", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-01T21:39:29", "normal": 11.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-01T21:39:29", "normal": 11.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T01:37:45", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T01:37:45", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T09:05:27", "normal": 4.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T09:05:27", "normal": 4.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T09:28:02", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T09:28:02", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T15:17:44", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T15:17:44", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T17:05:07", "normal": 5.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T21:57:29", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T21:57:29", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T22:31:41", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T23:58:14", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-02T23:58:14", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-03T06:23:16", "normal": 4.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-03T06:23:16", "normal": 4.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-03T13:07:10", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-03T13:07:10", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-03T17:36:24", "normal": 1.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-03T17:36:24", "normal": 1.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-03T19:19:53", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-04T20:39:32", "normal": 12.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-04T23:27:30", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-05T11:26:40", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-05T14:39:47", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-05T21:24:08", "normal": 12.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-05T23:47:57", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-06T10:29:13", "normal": 2.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-07T02:43:11", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-07T15:29:23", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-07T15:53:38", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-08T00:50:58", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-08T02:22:40", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-08T10:49:22", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-08T12:10:15", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-08T16:06:15", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-08T21:00:55", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-08T22:52:11", "normal": 13.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-09T06:48:05", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-09T11:57:20", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-09T14:50:09", "expectedNormal": 7.1, "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-09T15:09:57", "expectedNormal": 5.3, "normal": 0, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-09T15:10:07", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-09T15:45:24", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-09T19:08:06", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-10T00:20:48", "normal": 3.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-10T09:57:07", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-10T15:19:38", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-10T15:19:38", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-10T19:51:35", "normal": 6.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-10T21:04:03", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-11T17:21:27", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-11T23:50:01", "normal": 9.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-11T23:50:01", "normal": 9.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-12T14:21:27", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-13T01:22:50", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-13T09:16:42", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-13T09:45:20", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-13T17:59:12", "normal": 6.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-13T19:51:42", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-14T01:09:36", "normal": 5.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-14T01:09:36", "normal": 5.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-14T15:27:34", "normal": 6.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-14T15:37:30", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-14T19:52:15", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-14T22:44:38", "normal": 11, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-14T23:04:59", "expectedNormal": 8.7, "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-15T08:08:01", "normal": 5.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-15T08:08:01", "normal": 5.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-15T17:50:26", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-15T18:22:34", "normal": 4.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-15T22:12:43", "normal": 4.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-16T05:28:57", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-16T19:06:03", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-18T00:44:27", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-18T00:44:27", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-18T15:16:10", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-18T21:34:19", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-19T15:18:48", "normal": 7.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-19T15:18:48", "normal": 7.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-19T18:24:25", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-19T21:40:18", "normal": 5.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-20T01:57:09", "normal": 5.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-20T01:57:09", "normal": 5.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-20T05:21:15", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-20T14:43:26", "normal": 2.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-20T14:43:26", "normal": 2.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-20T20:23:29", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-20T23:15:21", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-21T01:47:25", "normal": 3.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-21T01:47:25", "normal": 3.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-21T16:32:58", "normal": 4.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-21T16:32:58", "normal": 4.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-21T21:12:41", "normal": 9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-22T13:07:23", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-22T13:24:37", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-22T13:38:43", "normal": 3.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-22T13:38:43", "normal": 3.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-22T14:23:46", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-23T00:01:17", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-23T02:53:10", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-23T10:26:09", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-23T12:45:53", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-23T19:04:33", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-24T02:03:30", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-24T02:03:30", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-24T08:42:05", "normal": 3.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-24T08:42:05", "normal": 3.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-24T09:11:28", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-24T13:05:25", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-24T16:20:41", "normal": 0.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-24T16:20:41", "normal": 0.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-24T19:39:24", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-24T22:58:57", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-24T22:58:57", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-25T09:05:32", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-25T09:15:49", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-25T10:05:32", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-25T15:20:46", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-26T00:34:00", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-26T00:40:32", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-26T17:42:21", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-27T00:26:46", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-27T01:56:53", "normal": 3.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-27T15:00:57", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-27T16:30:36", "normal": 0.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-28T00:07:24", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-28T04:04:35", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-28T11:06:58", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-28T12:05:56", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-28T17:32:14", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-28T22:51:31", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-29T09:24:11", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-29T11:48:49", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-01-31T17:35:53", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-01T22:39:45", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-01T23:11:22", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-02T05:32:22", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-02T13:53:59", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-02T15:01:02", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-03T11:47:19", "normal": 0.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-03T17:52:13", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-04T00:51:30", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-04T01:35:03", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-04T10:23:28", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-05T00:40:31", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-05T22:10:18", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-06T00:30:31", "duration": 9000000, "extended": 2.4, @@ -12022,7 +12024,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-06T00:30:31", "duration": 9000000, "extended": 2.4, @@ -12030,223 +12032,223 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-06T11:27:46", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-06T12:24:47", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-06T12:24:47", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-06T21:00:06", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-06T21:26:09", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-06T22:30:08", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-07T01:20:24", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-07T01:20:24", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-07T15:08:42", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-07T17:35:21", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-07T17:35:21", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-08T00:40:52", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-08T00:40:52", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-08T04:05:56", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-08T04:08:07", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-08T20:24:34", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-08T21:17:19", "normal": 9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-09T03:41:21", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-09T03:43:00", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-09T15:27:27", "normal": 4.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-09T15:27:27", "normal": 4.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-09T16:50:23", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-10T00:06:05", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-10T07:13:02", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-10T10:23:08", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-11T01:16:30", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-11T13:20:10", "normal": 1.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-11T13:20:10", "normal": 1.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-11T17:04:18", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-11T19:38:24", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-11T20:40:19", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-11T22:22:57", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-11T23:03:25", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-12T10:31:15", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-12T10:47:00", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-12T17:15:24", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-12T22:52:54", "duration": 5400000, "extended": 3.6, @@ -12254,7 +12256,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-12T22:52:54", "duration": 5400000, "extended": 3.6, @@ -12262,392 +12264,392 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-12T23:37:16", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-13T03:06:20", "expectedNormal": 2.4, "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-13T04:51:10", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-13T19:40:33", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-13T20:05:03", "normal": 0.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-14T17:20:11", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-14T17:56:34", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-15T01:56:38", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-15T17:29:22", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-16T09:23:19", "normal": 2.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-16T09:23:19", "normal": 2.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-17T11:56:27", "normal": 0.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-17T11:56:27", "normal": 0.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-18T00:34:51", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-18T04:32:23", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-18T12:15:36", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-18T12:56:37", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-18T20:43:52", "normal": 9.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-19T03:06:10", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-19T17:37:52", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-19T17:37:52", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-19T18:33:24", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-19T22:24:06", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-19T23:15:16", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-19T23:57:50", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-20T11:27:44", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-20T12:13:32", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-20T17:12:58", "normal": 7.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-20T17:12:58", "normal": 7.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-20T23:25:38", "normal": 4.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-20T23:25:38", "normal": 4.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-21T18:12:48", "normal": 4.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-21T23:02:43", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-22T05:11:08", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-22T12:46:46", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-22T18:44:55", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-22T23:47:30", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-23T15:22:30", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-24T01:28:13", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-24T04:50:59", "normal": 3.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-24T04:50:59", "normal": 3.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-24T10:06:16", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-24T10:57:20", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-24T16:20:38", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-24T20:57:10", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-24T21:10:06", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-25T01:46:05", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-25T03:01:41", "normal": 1.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-25T03:01:41", "normal": 1.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-25T12:45:34", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-25T16:35:50", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-25T16:43:09", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-26T14:50:38", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-26T23:18:20", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-27T19:10:37", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-27T19:56:05", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-27T20:05:22", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-02-27T20:33:26", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-01T11:06:45", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-01T13:38:00", "normal": 0.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-01T13:38:00", "normal": 0.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-01T17:26:06", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-02T05:10:59", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-02T14:53:50", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-02T15:15:41", "duration": 7200000, "extended": 4, @@ -12655,7 +12657,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-02T15:15:41", "duration": 7200000, "extended": 4, @@ -12663,508 +12665,508 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-02T17:55:24", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-02T21:27:07", "normal": 3.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-02T21:27:07", "normal": 3.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-03T02:23:28", "normal": 3.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-03T02:23:28", "normal": 3.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-03T07:55:24", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-03T13:31:37", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-03T17:33:40", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-04T01:00:34", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-04T09:51:54", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-04T13:59:53", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-04T14:53:15", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-04T17:26:51", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-04T19:38:13", "normal": 8.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-04T23:09:52", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-04T23:57:26", "normal": 1.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-04T23:57:26", "normal": 1.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-05T03:09:50", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-05T14:54:46", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-05T18:29:31", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-06T00:34:35", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-06T01:21:36", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-06T06:12:45", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-06T19:38:19", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-07T08:26:18", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-07T10:24:27", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-07T16:59:43", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-07T22:10:21", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-07T23:47:40", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-08T00:47:32", "duration": 10800000, "extended": 1.65, "subType": "square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-08T00:47:32", "duration": 10800000, "extended": 1.65, "subType": "square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-08T17:20:24", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-08T23:16:45", "normal": 2.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-08T23:16:45", "normal": 2.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-09T09:43:12", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-09T19:36:18", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-09T21:47:07", "normal": 11, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-09T22:28:29", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-10T00:56:27", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-10T05:18:33", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-10T10:09:03", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-10T19:08:41", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-10T19:30:42", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-10T21:00:08", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-10T21:11:26", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-11T00:12:25", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-11T00:12:25", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-11T03:50:32", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-11T09:48:55", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-11T17:56:25", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-11T21:45:42", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-11T23:48:21", "normal": 7.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-11T23:59:24", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-12T11:02:19", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-12T14:13:44", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-12T23:30:03", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-13T00:01:21", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-13T08:23:02", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-13T15:29:58", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-13T16:25:10", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-14T01:00:14", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-14T01:48:33", "duration": 7200000, "extended": 5, "subType": "square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-14T08:26:33", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-14T09:15:40", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-14T21:17:36", "normal": 5.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-14T21:36:42", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-15T01:00:44", "normal": 4.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-15T12:10:00", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-15T13:36:53", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-15T21:24:43", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-15T22:46:02", "normal": 10, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-16T19:49:33", "normal": 12.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-16T19:49:33", "normal": 12.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-17T15:56:01", "normal": 3.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-17T15:56:01", "normal": 3.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-18T10:02:04", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-18T15:29:15", "normal": 6.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-18T15:29:15", "normal": 6.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-18T16:27:25", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-18T21:15:02", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-19T06:28:44", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-19T15:28:25", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-19T22:15:08", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-20T08:14:49", "duration": 3600000, "extended": 1.5, @@ -13172,825 +13174,825 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-20T12:02:19", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-20T13:19:06", "normal": 0.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-20T16:07:19", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-20T19:43:27", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-20T20:56:53", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-21T00:32:48", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-21T14:39:05", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-21T21:09:21", "normal": 12, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-21T22:14:04", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-22T03:19:52", "expectedNormal": 5.15, "normal": 0.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-22T03:19:52", "expectedNormal": 5.15, "normal": 0.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-22T03:20:35", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-22T10:57:48", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-22T16:15:49", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-22T23:32:14", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-23T03:44:48", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-23T10:03:49", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-23T12:03:21", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-23T12:03:21", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-23T12:08:31", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-23T17:28:19", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-23T18:10:06", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-23T22:45:10", "normal": 6.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-23T23:57:11", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-24T01:52:51", "normal": 6.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-24T04:04:20", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-24T10:09:10", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-24T15:22:15", "normal": 9.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-24T15:59:21", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-24T18:45:12", "normal": 5.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-25T03:44:15", "normal": 6.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-25T04:12:56", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-25T13:25:50", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-25T15:47:08", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-25T16:27:53", "normal": 1.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-25T16:27:53", "normal": 1.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-25T17:26:51", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-26T01:03:51", "normal": 9.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-26T01:03:51", "normal": 9.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-26T04:48:39", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-26T15:52:08", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-26T18:11:28", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-26T21:42:00", "normal": 4.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-26T23:21:43", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-27T13:11:38", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-27T13:27:58", "normal": 5.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-27T13:43:12", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-27T14:19:41", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-28T01:21:26", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-28T02:49:55", "normal": 2.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-28T02:49:55", "normal": 2.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-28T12:09:39", "normal": 5.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-28T21:12:56", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-29T01:42:57", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-29T12:10:07", "normal": 8.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-29T12:10:07", "normal": 8.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-29T20:29:43", "normal": 8.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-29T20:29:43", "normal": 8.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-29T23:08:20", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-29T23:23:56", "expectedNormal": 2, "normal": 0.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-29T23:24:13", "expectedNormal": 3.8, "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-29T23:25:03", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-30T09:17:33", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-30T11:41:40", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-30T18:46:16", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-30T22:26:35", "normal": 7.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-30T22:26:35", "normal": 7.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-31T09:34:04", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-31T11:02:09", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-03-31T18:03:31", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-01T13:35:12", "normal": 4.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-01T19:00:43", "expectedNormal": 5.5, "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-02T11:24:01", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-02T11:24:01", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-03T00:24:02", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-03T00:24:02", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-03T04:46:03", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-03T13:58:14", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-03T15:41:52", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-03T22:48:16", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-03T22:48:16", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-03T22:53:19", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-03T23:37:06", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-04T17:49:44", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-04T18:25:58", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-04T20:06:51", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-04T20:50:31", "expectedNormal": 6.5, "normal": 4.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-04T21:47:42", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-05T11:10:22", "normal": 8.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-05T13:57:52", "normal": 5.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-05T14:41:02", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-05T19:55:35", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-05T20:07:23", "normal": 6.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-05T20:07:23", "normal": 6.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-05T23:10:52", "normal": 10.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-05T23:10:52", "normal": 10.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-06T17:04:13", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-07T00:30:35", "normal": 13, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-07T11:30:23", "expectedNormal": 11.3, "normal": 7.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-07T11:30:23", "expectedNormal": 11.3, "normal": 7.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-07T13:39:36", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-07T15:31:20", "normal": 7.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-07T17:03:27", "normal": 6.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-07T19:36:38", "normal": 11.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-07T19:36:38", "normal": 11.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T02:04:38", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T02:04:38", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T11:36:22", "normal": 4.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T11:36:22", "normal": 4.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T15:35:43", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T16:36:54", "normal": 4.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T17:06:19", "normal": 2.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T17:06:19", "normal": 2.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T18:36:43", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T20:45:53", "normal": 9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T21:43:56", "normal": 5.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T22:27:26", "normal": 8.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-08T22:27:26", "normal": 8.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-09T13:34:32", "normal": 4.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-09T13:34:32", "normal": 4.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-09T23:51:42", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-10T11:33:52", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-10T15:06:31", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-10T16:39:01", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-10T23:28:10", "normal": 2.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-10T23:28:10", "normal": 2.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-10T23:56:06", "normal": 3.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-10T23:56:06", "normal": 3.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-11T08:31:34", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-11T14:14:04", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-11T21:33:10", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-11T21:33:10", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-12T13:11:06", "normal": 5.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-12T15:22:32", "normal": 1.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-12T15:22:32", "normal": 1.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-12T20:37:48", "duration": 3600000, "extended": 1.4, @@ -13998,7 +14000,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-12T20:37:48", "duration": 3600000, "extended": 1.4, @@ -14006,49 +14008,49 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-13T07:00:52", "normal": 2.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-13T07:00:52", "normal": 2.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-13T11:55:34", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-13T15:38:33", "normal": 5.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-13T15:38:33", "normal": 5.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-13T16:43:21", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-13T22:25:40", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-13T23:43:31", "duration": 3600000, "extended": 3, @@ -14056,7 +14058,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-13T23:43:31", "duration": 3600000, "extended": 3, @@ -14064,695 +14066,695 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-14T07:24:30", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-14T11:26:07", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-14T14:02:33", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-14T16:13:29", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-14T16:21:37", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-15T04:30:42", "normal": 2.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-15T04:30:42", "normal": 2.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-15T11:27:28", "normal": 9.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-15T21:09:40", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-15T21:29:47", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-16T08:42:28", "normal": 3.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-16T08:42:28", "normal": 3.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-16T09:08:02", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-16T18:50:11", "normal": 7.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-16T18:50:11", "normal": 7.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-16T22:19:29", "normal": 8.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-16T22:19:29", "normal": 8.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-17T07:49:58", "expectedNormal": 6.25, "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-17T07:49:58", "expectedNormal": 6.25, "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-17T10:22:10", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-17T15:38:57", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-17T16:53:15", "normal": 4.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-17T16:53:15", "normal": 4.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-17T23:01:44", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-17T23:01:44", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-17T23:17:46", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-18T03:36:54", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-18T08:15:40", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-18T13:03:08", "normal": 6.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-18T13:03:08", "normal": 6.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-18T22:49:11", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-19T10:49:57", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-19T10:49:57", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-19T12:47:07", "normal": 7.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-19T12:47:07", "normal": 7.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-19T18:51:49", "normal": 0.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-19T18:51:49", "normal": 0.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T00:34:12", "normal": 4.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T00:34:12", "normal": 4.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T11:55:56", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T11:55:56", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T12:21:25", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T12:25:59", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T12:40:44", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T16:51:52", "normal": 5.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T16:51:52", "normal": 5.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T17:13:53", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T18:53:57", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T21:13:02", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T21:17:28", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-20T22:56:20", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-21T05:00:30", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-21T05:00:30", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-21T14:57:12", "expectedNormal": 5.7, "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-21T17:25:57", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-21T19:55:14", "normal": 5.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-21T20:21:02", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-21T20:48:12", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-21T23:36:01", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-22T00:17:02", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-22T07:20:00", "normal": 3.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-22T07:20:00", "normal": 3.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-22T09:32:51", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-22T15:34:54", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-22T17:17:07", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-22T18:33:33", "normal": 8.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-22T19:56:36", "normal": 4.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-22T21:38:22", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-23T14:44:27", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-23T16:39:55", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-23T17:17:36", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-23T18:45:04", "normal": 2.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-23T21:54:57", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-23T23:08:34", "expectedNormal": 2.5, "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-23T23:30:54", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-24T10:55:10", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-24T16:10:07", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-24T16:10:07", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-24T18:45:06", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-24T18:45:06", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-24T21:29:29", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-25T02:05:38", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-25T16:31:35", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-25T16:52:59", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-25T23:23:29", "normal": 9.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-25T23:23:29", "normal": 9.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-26T10:15:03", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-26T13:15:18", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-26T13:53:04", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-26T15:43:54", "normal": 4.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-26T20:06:36", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-27T12:42:46", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-27T15:48:19", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-27T15:53:18", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-27T23:14:39", "normal": 9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-28T02:49:38", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-28T14:15:39", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-28T14:15:39", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-28T15:36:19", "normal": 3.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-28T17:22:40", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-28T23:33:46", "normal": 6.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-29T12:43:56", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-29T14:24:57", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-29T16:00:35", "normal": 0.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-29T16:00:35", "normal": 0.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-29T22:51:00", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-30T16:41:59", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-30T23:51:20", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-04-30T23:51:20", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-01T00:40:06", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-01T02:19:29", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-01T15:47:28", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-01T17:58:20", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-01T17:58:20", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-02T01:01:32", "duration": 5400000, "extended": 1.85, @@ -14760,7 +14762,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-02T01:01:32", "duration": 5400000, "extended": 1.85, @@ -14768,907 +14770,907 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-02T14:35:54", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-02T16:30:55", "normal": 1.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-02T16:30:55", "normal": 1.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-02T18:03:13", "normal": 2.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-02T18:03:13", "normal": 2.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-02T18:30:32", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-02T22:44:03", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-03T13:28:40", "normal": 7.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-03T13:28:40", "normal": 7.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-03T22:38:40", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-03T22:38:40", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-04T06:40:11", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-04T12:09:02", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-04T12:42:38", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-04T13:58:04", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-04T19:31:20", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-04T19:31:20", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-05T13:12:58", "normal": 5.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-05T13:12:58", "normal": 5.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-05T17:02:00", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-05T17:02:00", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-05T22:18:24", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-05T22:18:24", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-06T12:34:16", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-06T20:28:21", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-06T21:05:28", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-07T10:11:40", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-07T12:47:09", "normal": 4.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-07T12:47:09", "normal": 4.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-07T20:59:51", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-07T21:46:06", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-08T07:29:03", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-08T07:29:03", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-08T13:44:00", "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-08T13:44:00", "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-08T20:00:38", "normal": 2.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-08T20:00:38", "normal": 2.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-09T14:28:06", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-09T14:28:06", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-09T23:50:14", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-10T10:13:12", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-10T12:28:54", "normal": 2.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-10T12:28:54", "normal": 2.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-10T14:38:18", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-10T18:48:40", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-10T18:48:40", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-10T19:22:11", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-10T20:10:02", "normal": 0.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-10T20:10:02", "normal": 0.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-10T20:43:41", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-11T02:11:06", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-11T15:22:52", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-11T19:51:32", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-11T20:01:17", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-11T21:07:27", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-11T22:40:53", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-12T00:51:28", "normal": 5.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-12T00:51:28", "normal": 5.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-12T09:31:50", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-12T17:24:32", "normal": 4.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-12T17:31:58", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-12T19:20:54", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-12T20:09:19", "normal": 6.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-12T23:53:39", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-13T06:04:08", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-13T09:33:30", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-13T09:33:30", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-13T10:02:35", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-13T13:25:22", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-13T14:39:05", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-13T21:27:31", "normal": 5.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-13T21:49:54", "normal": 4.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-13T21:49:54", "normal": 4.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-14T06:30:45", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-14T17:13:50", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-14T17:13:50", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-14T19:51:30", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-15T02:59:12", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-15T18:34:17", "normal": 8.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-15T18:34:17", "normal": 8.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-15T20:03:48", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-15T20:13:10", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-15T21:08:56", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-15T21:38:31", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-16T11:44:10", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-16T13:54:41", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-16T17:33:07", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-16T18:59:52", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-16T22:40:06", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-16T22:40:06", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-17T10:47:43", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-17T17:33:07", "normal": 1.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-17T17:33:07", "normal": 1.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-17T21:09:30", "normal": 8.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-17T21:09:30", "normal": 8.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-17T21:38:23", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-17T21:38:23", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-18T14:40:29", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-18T16:20:15", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-18T17:18:29", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-18T21:04:49", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-18T21:04:49", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-19T08:29:53", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-19T08:29:53", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-19T10:55:07", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-19T13:03:51", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-19T20:15:44", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-19T20:28:37", "normal": 10.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-19T20:28:37", "normal": 10.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-20T00:18:39", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-20T01:24:17", "normal": 0.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-20T01:24:17", "normal": 0.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-20T07:49:45", "normal": 0.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-20T07:49:45", "normal": 0.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-20T11:51:55", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-20T12:13:22", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-20T14:57:44", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-20T18:03:00", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-21T10:31:41", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-21T10:31:41", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-21T13:57:19", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-21T19:23:59", "normal": 10, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-21T19:23:59", "normal": 10, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-21T22:46:23", "normal": 3.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-22T09:51:09", "normal": 9.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-22T09:51:09", "normal": 9.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-22T19:41:23", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-22T19:41:23", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-22T22:49:19", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-23T07:43:22", "normal": 5.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-23T07:43:22", "normal": 5.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-23T15:05:51", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-23T15:05:51", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-23T16:43:30", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-23T16:43:30", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-23T20:24:21", "normal": 10.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-23T20:24:21", "normal": 10.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-23T20:36:41", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-24T01:31:04", "normal": 3.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-24T01:31:04", "normal": 3.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-24T12:17:15", "normal": 4.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-24T12:17:15", "normal": 4.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-24T13:52:54", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-24T22:00:26", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-24T22:31:42", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-24T22:31:42", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-25T07:08:36", "normal": 3.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-25T07:08:36", "normal": 3.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-25T09:25:26", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-25T09:25:26", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-25T10:43:07", "duration": 3600000, "extended": 2.15, @@ -15676,7 +15678,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-25T10:43:07", "duration": 3600000, "extended": 2.15, @@ -15684,620 +15686,620 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-25T15:29:54", "normal": 5.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-25T19:28:58", "normal": 4.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-25T21:48:56", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-26T07:47:05", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-26T15:09:57", "normal": 3.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-26T15:23:19", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-26T19:21:32", "normal": 3.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-26T19:21:32", "normal": 3.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-26T22:54:32", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-27T08:07:50", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-27T08:07:50", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-27T12:47:09", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-27T12:47:09", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-27T13:23:20", "normal": 1.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-27T13:23:20", "normal": 1.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-27T17:55:40", "normal": 7.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-27T19:30:40", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-27T22:57:00", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-28T02:25:19", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-28T16:54:27", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-28T16:54:27", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-28T17:18:04", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-28T19:15:15", "normal": 6.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-28T20:51:16", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-28T23:10:50", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-29T01:18:06", "normal": 1.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-29T01:18:06", "normal": 1.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-29T14:47:42", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-29T16:34:10", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-29T22:26:32", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-31T04:03:49", "normal": 4.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-31T10:56:21", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-31T13:27:12", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-31T19:41:58", "normal": 2.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-31T19:41:58", "normal": 2.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-31T21:08:12", "normal": 5.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-31T21:08:12", "normal": 5.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-31T22:40:45", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-05-31T23:11:40", "normal": 5.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-01T11:33:30", "normal": 2.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-01T11:33:30", "normal": 2.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-01T20:49:42", "normal": 5.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-01T20:49:42", "normal": 5.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-01T23:31:41", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-02T02:42:26", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-02T02:42:26", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-02T03:08:32", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-02T12:36:04", "normal": 7.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-02T12:36:04", "normal": 7.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-02T13:23:44", "normal": 4.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-02T20:07:26", "normal": 7.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-03T15:01:33", "normal": 0.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-03T15:46:39", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-03T16:41:33", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-03T17:18:38", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-03T17:43:38", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-04T10:16:53", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-04T14:50:00", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-04T16:14:19", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-04T19:21:41", "normal": 8.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-04T19:21:41", "normal": 8.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-04T23:46:41", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-05T00:44:34", "expectedNormal": 2, "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-05T01:02:58", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-05T12:01:09", "normal": 2.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-05T12:01:09", "normal": 2.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-05T12:23:18", "normal": 0.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-05T12:51:54", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-05T15:39:48", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-05T15:39:48", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-05T21:29:36", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-05T21:29:36", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-06T04:21:34", "normal": 2.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-06T04:21:34", "normal": 2.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-06T08:53:58", "normal": 1.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-06T08:53:58", "normal": 1.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-07T15:08:48", "normal": 0.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-10T19:54:26", "normal": 7.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-08T15:53:04", "normal": 5.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-08T15:53:04", "normal": 5.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-08T22:22:31", "normal": 7.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-08T22:47:20", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-09T15:51:36", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-10T00:59:27", "normal": 1.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-10T00:59:27", "normal": 1.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-10T10:23:36", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-10T18:30:44", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-10T18:39:41", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-10T18:39:41", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-10T19:47:34", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-11T13:53:18", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-11T20:58:05", "normal": 10, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-12T00:35:54", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-12T13:04:51", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-12T17:37:35", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-12T19:09:48", "normal": 1.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-12T19:09:48", "normal": 1.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-12T19:34:40", "normal": 0.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-13T00:02:43", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-13T00:11:41", "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-13T00:11:41", "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-13T08:33:39", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-13T20:19:52", "duration": 1800000, "extended": 2.55, @@ -16305,7 +16307,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-13T20:19:52", "duration": 1800000, "extended": 2.55, @@ -16313,109 +16315,109 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-14T16:44:31", "normal": 8.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-14T16:44:31", "normal": 8.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-14T22:46:55", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-15T00:28:57", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-15T08:51:33", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-15T11:33:53", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-15T19:09:51", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-16T17:02:11", "normal": 3.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-16T17:02:11", "normal": 3.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-16T18:49:50", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-16T20:22:02", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-17T11:14:04", "normal": 0.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-17T19:29:27", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-18T06:45:25", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-18T15:28:35", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-18T16:20:17", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-18T16:50:44", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-18T22:16:57", "duration": 3600000, "extended": 4.2, @@ -16423,7 +16425,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-18T22:16:57", "duration": 3600000, "extended": 4.2, @@ -16431,43 +16433,43 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-19T07:18:23", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-19T18:51:48", "normal": 4.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-19T18:51:48", "normal": 4.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-20T08:50:29", "normal": 0.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-20T11:19:38", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-20T11:19:38", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-20T15:42:53", "duration": 1800000, "extended": 0.45, @@ -16475,7 +16477,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-20T15:42:53", "duration": 1800000, "extended": 0.45, @@ -16483,7 +16485,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-20T17:25:24", "duration": 3600000, "extended": 0.75, @@ -16491,7 +16493,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-20T17:25:24", "duration": 3600000, "extended": 0.75, @@ -16499,7 +16501,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-20T21:38:30", "duration": 3600000, "extended": 2.85, @@ -16507,7 +16509,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-20T21:38:30", "duration": 3600000, "extended": 2.85, @@ -16515,7 +16517,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-21T11:54:08", "duration": 3600000, "extended": 2.8, @@ -16523,73 +16525,73 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-21T14:39:04", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-21T14:39:04", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-21T18:23:31", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-21T19:29:16", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-21T20:00:12", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-21T20:00:12", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-21T21:40:40", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-21T23:42:55", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-22T00:24:30", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-22T08:20:59", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-22T08:20:59", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-22T21:37:44", "duration": 3600000, "extended": 1.2, @@ -16597,7 +16599,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-22T21:37:44", "duration": 3600000, "extended": 1.2, @@ -16605,43 +16607,43 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-22T22:25:47", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-22T23:37:05", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-22T23:37:05", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-23T07:32:39", "normal": 1.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-23T07:32:39", "normal": 1.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-23T19:09:07", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-23T20:27:18", "duration": 3600000, "extended": 1.75, @@ -16649,494 +16651,494 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-23T22:28:35", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-23T23:23:04", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T08:19:28", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T08:19:28", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T09:04:06", "normal": 1.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T09:04:06", "normal": 1.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T10:00:56", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T10:00:56", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T18:30:46", "normal": 4.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T18:30:46", "normal": 4.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T19:44:10", "normal": 1.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T19:44:10", "normal": 1.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T20:32:30", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T20:39:38", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-24T20:39:38", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-25T09:17:23", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-25T16:59:11", "normal": 3.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-25T16:59:11", "normal": 3.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-25T17:49:12", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-25T19:55:43", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-25T19:55:43", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-26T03:01:17", "normal": 1.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-26T03:01:17", "normal": 1.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-26T07:05:35", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-26T09:44:50", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-26T09:44:50", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-27T16:48:06", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-27T17:13:45", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-27T17:57:18", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-27T22:06:32", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-27T22:06:32", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-28T15:46:44", "normal": 6.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-28T15:46:44", "normal": 6.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-28T16:18:13", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-28T16:23:18", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-28T16:28:41", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-29T18:27:23", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-29T18:27:23", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-30T12:43:51", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-06-30T12:43:51", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-01T17:46:55", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-01T17:46:55", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-01T18:30:32", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-01T18:51:38", "normal": 4.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-01T18:51:38", "normal": 4.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-02T00:15:19", "normal": 4.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-02T00:15:19", "normal": 4.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-02T06:49:58", "normal": 1.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-02T06:49:58", "normal": 1.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-02T18:35:00", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-02T18:35:00", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-03T12:03:51", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-03T12:50:24", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-03T17:08:12", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-03T17:41:00", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-03T17:41:00", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-03T19:08:04", "expectedNormal": 2, "normal": 0.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-03T19:08:18", "normal": 0.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-04T01:21:22", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-04T14:10:31", "normal": 1.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-04T14:10:31", "normal": 1.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-04T17:59:30", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-04T17:59:30", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-04T19:21:37", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-04T19:21:37", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-04T19:25:51", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-04T20:09:01", "normal": 7.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-04T20:09:01", "normal": 7.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-05T02:02:39", "normal": 1.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-05T02:02:39", "normal": 1.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-05T02:36:40", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-05T13:58:30", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-05T13:58:30", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-05T17:17:54", "normal": 6.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-05T17:17:54", "normal": 6.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-05T23:40:50", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-05T23:40:50", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-06T01:28:33", "normal": 3.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-06T01:28:33", "normal": 3.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-06T14:59:11", "normal": 2.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-06T14:59:11", "normal": 2.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-06T20:26:50", "duration": 3600000, "extended": 2, @@ -17144,7 +17146,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-06T20:26:50", "duration": 3600000, "extended": 2, @@ -17152,19 +17154,19 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-07T00:48:50", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-07T14:09:43", "normal": 3.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-07T16:02:12", "duration": 5400000, "extended": 3.25, @@ -17172,55 +17174,55 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-08T18:17:26", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-08T18:29:06", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-08T20:29:43", "normal": 5.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-08T20:29:43", "normal": 5.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-08T23:53:16", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-08T23:53:16", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-09T12:19:24", "normal": 5.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-09T12:19:24", "normal": 5.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-09T16:27:30", "duration": 3600000, "extended": 1, @@ -17228,7 +17230,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-09T16:27:30", "duration": 3600000, "extended": 1, @@ -17236,331 +17238,331 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-09T17:50:34", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-10T00:25:49", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-10T17:43:21", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-10T18:08:03", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-11T13:06:32", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-11T19:37:52", "normal": 7.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-11T19:37:52", "normal": 7.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-12T00:07:01", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-12T00:07:01", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-12T00:42:51", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-12T07:40:06", "normal": 3.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-12T07:40:06", "normal": 3.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-12T08:50:10", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-12T16:09:42", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-12T21:45:57", "normal": 6.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-12T21:45:57", "normal": 6.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-13T10:56:43", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-13T11:42:47", "normal": 1.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-13T11:42:47", "normal": 1.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-13T16:33:50", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-13T18:21:41", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-13T22:13:37", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-13T22:19:30", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-13T22:48:14", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-13T23:08:30", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-14T14:31:41", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-14T15:53:20", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-14T17:37:39", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-14T18:15:11", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-14T20:29:30", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-15T12:18:56", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-15T14:09:52", "normal": 4.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-15T14:09:52", "normal": 4.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-15T17:23:04", "normal": 2.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-15T17:23:04", "normal": 2.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-15T21:15:01", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-15T21:44:35", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-15T22:12:37", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-15T22:57:20", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-15T22:58:49", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-16T09:35:57", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-16T11:31:07", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-16T15:12:49", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-16T15:41:21", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-16T21:04:38", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-17T03:22:39", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-17T03:22:39", "normal": 1.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-17T14:09:57", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-17T16:29:43", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-17T16:29:43", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-18T05:26:35", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-18T05:26:35", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-18T08:03:17", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-18T17:58:39", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-18T20:40:22", "duration": 1800000, "extended": 5.7, @@ -17568,7 +17570,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-18T20:40:22", "duration": 1800000, "extended": 5.7, @@ -17576,43 +17578,43 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-19T08:36:08", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-19T15:20:39", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-19T18:22:28", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-19T18:54:15", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-19T22:20:06", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-19T22:47:22", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-20T14:23:03", "duration": 3600000, "extended": 1.35, @@ -17620,7 +17622,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-20T14:23:03", "duration": 3600000, "extended": 1.35, @@ -17628,97 +17630,97 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-20T15:02:15", "normal": 3.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-20T15:50:21", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-21T00:08:35", "normal": 1.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-21T00:08:35", "normal": 1.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-21T12:12:24", "normal": 5.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-21T12:12:24", "normal": 5.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-21T15:13:53", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-21T15:13:53", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-22T16:11:14", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-23T01:06:51", "normal": 2.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-23T01:06:51", "normal": 2.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-23T10:37:02", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-23T16:18:09", "normal": 6.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-23T16:18:09", "normal": 6.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-23T16:57:31", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-23T21:30:01", "duration": 1800000, "extended": 3.55, @@ -17726,7 +17728,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-23T21:30:01", "duration": 1800000, "extended": 3.55, @@ -17734,193 +17736,193 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-24T08:03:19", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-24T13:21:49", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-24T13:41:26", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-24T15:13:42", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-24T17:30:34", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-24T18:47:01", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-25T00:37:32", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-25T15:27:34", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-25T15:50:46", "normal": 6.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-25T18:34:45", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-25T18:34:45", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-26T08:00:02", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-26T15:30:21", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-26T15:30:21", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-26T16:43:37", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-26T22:55:06", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-27T00:34:23", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-27T16:08:38", "normal": 5.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-28T10:22:34", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-28T10:42:12", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-28T11:14:05", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-28T12:22:02", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-28T12:22:02", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-28T17:58:24", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-29T00:59:10", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-29T13:21:48", "normal": 3.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-29T13:21:48", "normal": 3.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-29T14:26:37", "normal": 5.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-29T14:26:37", "normal": 5.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-29T15:29:23", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-29T19:11:00", "normal": 3.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-29T21:59:18", "duration": 10800000, "extended": 8.65, @@ -17928,7 +17930,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-29T21:59:18", "duration": 10800000, "extended": 8.65, @@ -17936,43 +17938,43 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-30T07:29:04", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-30T11:32:41", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-30T11:32:41", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-30T13:33:42", "normal": 2.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-30T13:33:42", "normal": 2.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-30T15:10:57", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-30T16:48:04", "duration": 2700000, "expectedDuration": 3600000, @@ -17982,7 +17984,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-30T16:48:04", "duration": 2700000, "expectedDuration": 3600000, @@ -17992,266 +17994,266 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-30T17:35:25", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-31T06:01:14", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-31T08:02:24", "expectedNormal": 1.8, "normal": 0, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-31T17:32:27", "normal": 2.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-31T17:32:27", "normal": 2.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-31T19:24:54", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-31T20:15:14", "normal": 7.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-31T20:15:14", "normal": 7.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-07-31T23:11:02", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-01T15:38:03", "normal": 7.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-02T00:53:24", "normal": 1.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-02T00:53:24", "normal": 1.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-02T09:42:56", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-02T12:33:40", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-03T13:13:56", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-03T13:13:56", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-03T13:30:33", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-03T19:02:46", "normal": 7.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-03T19:02:46", "normal": 7.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-03T23:23:36", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-03T23:30:48", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-04T07:57:10", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-04T17:05:51", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-04T18:14:03", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-05T16:45:27", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-05T19:47:08", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-06T09:25:42", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-06T15:20:44", "normal": 5.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-06T16:19:31", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-06T17:07:49", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-06T19:58:23", "normal": 7.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-06T19:58:23", "normal": 7.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-07T14:38:43", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-07T19:47:20", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-07T20:51:30", "normal": 8.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-07T20:51:30", "normal": 8.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-07T21:31:38", "normal": 5.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-07T21:31:38", "normal": 5.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-08T01:05:38", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-08T10:11:09", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-08T15:43:17", "normal": 6.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-08T15:43:17", "normal": 6.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-08T19:52:56", "normal": 0.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-08T20:57:40", "duration": 3600000, "extended": 2, @@ -18259,7 +18261,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-08T20:57:40", "duration": 3600000, "extended": 2, @@ -18267,701 +18269,701 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-09T09:07:47", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-09T16:17:45", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-09T17:24:45", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-11T01:12:55", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-11T18:24:34", "normal": 5.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-11T18:24:34", "normal": 5.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-11T19:04:48", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-11T20:30:46", "normal": 0.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-11T20:30:46", "normal": 0.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-12T10:04:06", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-13T17:30:51", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-13T18:15:01", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-13T18:15:01", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-13T18:43:29", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-14T15:37:44", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-15T01:47:54", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-15T13:59:56", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-15T14:41:43", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-15T14:44:38", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-15T21:54:18", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-16T15:51:57", "normal": 7.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-16T15:51:57", "normal": 7.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-16T16:23:22", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-16T20:59:44", "normal": 7.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-16T20:59:44", "normal": 7.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-16T22:28:09", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-17T13:43:39", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-17T15:22:58", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-17T20:43:00", "normal": 4.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-17T20:43:00", "normal": 4.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-17T22:37:07", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-17T22:37:07", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-18T12:51:55", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-18T15:37:39", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-18T15:37:39", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-18T16:20:47", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-18T16:23:34", "expectedNormal": 1, "normal": 0, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-18T16:23:47", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-19T01:18:52", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-19T18:35:04", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-19T18:35:04", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-19T18:45:16", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-19T19:19:18", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-19T19:49:49", "normal": 9.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-20T13:23:57", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-20T13:23:57", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-20T18:56:03", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-20T18:56:03", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-21T18:29:04", "normal": 8.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-21T18:29:04", "normal": 8.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-21T20:46:21", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-21T20:46:21", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-22T21:10:05", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-22T21:58:04", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-22T22:02:55", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-23T18:27:37", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-23T18:27:37", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-23T20:31:41", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-23T20:59:54", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-23T23:21:11", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-24T10:24:29", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-24T17:07:32", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-24T17:33:08", "normal": 0.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-24T18:35:51", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-25T14:07:13", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-25T17:12:17", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-25T21:24:58", "normal": 8.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-26T11:35:34", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-26T11:48:12", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-26T12:08:19", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-26T16:13:11", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-26T22:12:41", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-27T01:27:13", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-27T16:56:37", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-27T19:56:41", "normal": 1.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-27T20:22:28", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-27T20:57:07", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-28T07:42:06", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-28T07:42:06", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-28T09:05:30", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-28T09:05:30", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-28T09:54:05", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-28T09:54:05", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-28T14:01:25", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-28T15:50:43", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-28T20:59:49", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-28T21:29:58", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-29T01:28:07", "expectedNormal": 3, "normal": 0, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-29T01:28:23", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-29T05:09:40", "expectedNormal": 2.55, "normal": 1.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-29T05:09:40", "expectedNormal": 2.55, "normal": 1.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-29T05:18:26", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-29T05:18:26", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-29T06:58:48", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-29T07:02:43", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-29T13:23:14", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-29T21:18:42", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-29T21:18:42", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-30T15:27:04", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-30T15:45:46", "normal": 5.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-30T16:03:48", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-30T21:27:24", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-31T00:32:49", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-31T00:32:49", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-08-31T14:12:55", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-01T00:10:43", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-01T00:20:00", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-01T01:11:31", "normal": 5.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-01T18:11:06", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-01T18:59:49", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-01T18:59:49", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-01T23:21:40", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T01:17:05", "normal": 2.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T07:22:03", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T09:19:07", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T15:32:12", "duration": 3600000, "extended": 1.65, @@ -18969,7 +18971,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T15:32:12", "duration": 3600000, "extended": 1.65, @@ -18977,433 +18979,433 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T17:09:29", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T19:39:58", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T19:39:58", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T20:38:24", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T20:38:24", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T20:44:02", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-02T21:40:20", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-03T00:20:40", "normal": 3.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-03T00:20:40", "normal": 3.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-03T06:42:57", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-03T14:08:27", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-03T14:48:55", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-03T17:14:46", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-03T22:34:31", "normal": 5.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-04T00:28:34", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-04T06:09:22", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-04T14:45:39", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-04T18:24:53", "normal": 10.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-05T01:06:54", "normal": 6.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-05T16:22:33", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-05T16:58:48", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-05T21:45:50", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-06T00:55:25", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-06T15:41:42", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-06T15:45:31", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-06T16:47:53", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-06T21:15:40", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-06T21:15:40", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-07T19:12:03", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-07T19:57:42", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-07T20:27:57", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-07T23:09:54", "normal": 10.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-08T06:49:54", "normal": 5.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-08T13:38:14", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-08T19:03:48", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-08T21:12:03", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-08T22:21:55", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-09T01:19:46", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-09T15:05:45", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-09T22:54:59", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-09T23:26:51", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-10T16:45:44", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-10T17:22:05", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-10T20:02:24", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-10T22:48:01", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-10T23:18:10", "normal": 4.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-11T17:11:53", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-11T23:15:24", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-12T00:04:13", "normal": 2.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-12T00:04:13", "normal": 2.25, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-12T00:28:22", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-12T15:21:56", "normal": 4.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-13T15:59:02", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-13T22:06:29", "normal": 6.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-14T11:11:32", "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-14T13:09:35", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-14T19:24:39", "normal": 10.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-14T19:24:39", "normal": 10.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-15T15:36:19", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-15T21:46:47", "normal": 5.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-15T21:46:47", "normal": 5.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-15T22:10:16", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-16T15:44:33", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-16T21:36:53", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-17T15:59:12", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-17T16:08:56", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-17T21:09:25", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-17T21:09:25", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-18T09:37:49", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-18T18:20:54", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-18T18:51:09", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-19T13:27:26", "duration": 3600000, "extended": 0.55, @@ -19411,7 +19413,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-19T13:27:26", "duration": 3600000, "extended": 0.55, @@ -19419,1347 +19421,1347 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-19T14:53:40", "normal": 4.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-19T14:53:40", "normal": 4.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-19T15:24:30", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-20T18:32:41", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-20T21:29:36", "normal": 5.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-21T15:35:49", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-21T15:35:49", "normal": 5.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-21T21:03:52", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-21T22:39:49", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-22T11:25:56", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-22T13:19:40", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-22T17:25:35", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-22T19:59:31", "normal": 2.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-22T22:50:19", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-23T11:45:40", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-23T11:47:49", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-23T12:07:32", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-23T15:08:45", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-23T20:33:01", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-23T22:00:40", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-24T06:08:59", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-24T08:33:59", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-24T11:22:33", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-24T21:52:26", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-24T22:08:46", "normal": 7.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-25T16:52:46", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-25T20:23:33", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-25T20:36:44", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-26T07:18:20", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-26T10:15:04", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-26T16:11:43", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-26T19:25:09", "normal": 6.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-26T21:22:26", "normal": 1.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-26T21:22:26", "normal": 1.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-27T12:14:07", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-27T13:57:02", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-27T14:09:20", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-27T15:29:54", "normal": 2.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-27T20:48:41", "normal": 2.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-27T21:12:09", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-27T21:20:49", "normal": 7.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-27T21:49:25", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-28T04:50:11", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-28T07:40:45", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-28T12:06:19", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-28T15:46:19", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-28T15:46:19", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-28T21:47:01", "normal": 12.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-28T21:47:01", "normal": 12.35, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-29T01:12:35", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-29T02:08:17", "normal": 2.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-29T02:59:26", "normal": 0.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-29T14:42:33", "normal": 7.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-29T14:42:33", "normal": 7.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-29T15:02:43", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-29T15:12:10", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-29T19:10:18", "normal": 5.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-29T19:46:49", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-30T11:29:40", "normal": 10, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-30T13:56:15", "normal": 5.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-30T15:42:59", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-30T22:53:22", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-30T23:05:22", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-09-30T23:35:16", "normal": 7.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-01T14:27:43", "normal": 1.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-01T16:04:42", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-01T22:28:45", "normal": 6.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-01T22:28:45", "normal": 6.85, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-02T17:01:12", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-02T17:01:12", "normal": 0.7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-02T18:18:32", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-02T22:08:17", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-02T22:56:37", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-03T07:44:00", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-03T08:42:58", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-03T15:24:28", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-03T15:24:28", "normal": 3.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-03T17:53:59", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-03T17:53:59", "normal": 0.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-03T19:00:37", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-03T22:17:33", "normal": 7.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-03T22:17:33", "normal": 7.65, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-04T09:52:11", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-04T12:55:58", "normal": 2.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-04T12:55:58", "normal": 2.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-04T15:12:11", "normal": 6.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-04T20:09:22", "normal": 3.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-05T03:27:19", "normal": 4.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-05T03:27:19", "normal": 4.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-05T19:22:47", "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-05T19:22:47", "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-05T22:39:45", "normal": 10.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-05T22:39:45", "normal": 10.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-06T06:12:37", "normal": 4.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-06T06:12:37", "normal": 4.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-06T12:42:06", "normal": 8.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-06T15:32:00", "expectedNormal": 4.7, "normal": 2.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-06T19:07:20", "normal": 4.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-06T19:39:58", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-07T00:20:47", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-07T05:30:49", "normal": 2.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-07T08:21:15", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-07T22:44:14", "normal": 8.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-08T06:58:25", "normal": 4.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-08T08:16:59", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-08T13:52:10", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-08T19:52:08", "normal": 5.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-08T19:52:08", "normal": 5.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-09T06:26:22", "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-09T06:26:22", "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-09T07:43:04", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-09T15:08:46", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-09T15:54:44", "normal": 3.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-09T23:03:47", "normal": 4.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-09T23:38:04", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-09T23:38:04", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-10T16:02:43", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-10T22:56:35", "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-10T22:56:35", "normal": 3.45, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-10T23:35:59", "normal": 2.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-11T15:03:25", "normal": 3.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-11T15:03:25", "normal": 3.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-11T16:13:04", "normal": 2.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-11T21:19:03", "normal": 7.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-11T21:19:03", "normal": 7.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-12T07:22:58", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-12T15:16:54", "normal": 3.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-12T15:16:54", "normal": 3.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-12T15:54:25", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-12T21:11:04", "normal": 4.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-12T21:11:04", "normal": 4.05, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-13T13:15:55", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-13T13:18:43", "normal": 5.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-13T13:18:43", "normal": 5.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-13T16:26:19", "normal": 6.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-13T16:26:19", "normal": 6.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-13T20:33:47", "normal": 8.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-13T20:33:47", "normal": 8.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-13T20:49:06", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-13T21:24:48", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-13T23:18:40", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-13T23:45:17", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-14T00:25:53", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-14T01:10:52", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-14T12:00:00", "normal": 3.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-14T15:36:08", "normal": 1.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-14T16:01:10", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-14T19:58:59", "normal": 3.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-14T20:51:48", "normal": 8.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-14T20:51:48", "normal": 8.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-14T21:40:26", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-14T23:14:13", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-15T00:33:52", "normal": 3.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-15T00:33:52", "normal": 3.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-15T08:45:17", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-15T15:49:05", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-15T21:53:25", "normal": 8.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-15T21:53:25", "normal": 8.75, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-15T22:38:18", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-16T16:47:33", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-16T22:22:47", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-16T23:27:48", "normal": 14.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-17T15:50:12", "normal": 3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-17T15:52:31", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-18T14:12:19", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-18T15:09:54", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-18T15:27:12", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-18T15:57:46", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-18T23:28:05", "normal": 8.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-18T23:28:05", "normal": 8.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-19T00:10:14", "normal": 5.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-19T00:46:24", "normal": 5.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-19T01:11:02", "normal": 5.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-19T14:59:14", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-19T16:28:00", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-19T22:00:22", "normal": 6.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-19T23:24:34", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-20T17:39:33", "normal": 4.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-20T19:27:43", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-20T20:07:49", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-20T20:43:12", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-20T21:54:33", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-21T14:16:42", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-21T20:42:35", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-22T12:14:12", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-23T07:12:15", "normal": 3.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-23T11:12:32", "normal": 1.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-23T12:36:16", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-23T12:50:53", "normal": 8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-23T14:17:09", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-24T10:47:06", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-24T14:20:06", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-24T16:11:40", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-25T00:18:43", "normal": 0.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-25T19:12:42", "normal": 3.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-25T19:12:42", "normal": 3.95, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-25T20:42:26", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-25T20:42:26", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-26T18:49:01", "normal": 4.6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-27T18:11:11", "normal": 2.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-27T20:47:51", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-28T13:28:57", "normal": 1.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-28T13:31:35", "normal": 5.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-28T13:43:39", "normal": 1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-28T18:08:08", "normal": 2.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-29T03:56:45", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-29T03:56:45", "normal": 4.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-29T15:09:37", "normal": 5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-29T15:58:27", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-29T15:58:27", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-30T02:57:09", "normal": 4.8, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-30T16:34:05", "normal": 10, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-30T19:17:07", "expectedNormal": 8, "normal": 6.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-30T23:28:05", "normal": 1.3, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-10-31T20:19:12", "normal": 6, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-01T16:10:05", "normal": 7, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-01T23:01:05", "normal": 3.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-01T23:01:05", "normal": 3.15, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-02T17:16:10", "normal": 4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-02T23:46:20", "normal": 8.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-03T12:56:37", "normal": 6.1, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-03T13:09:30", "normal": 7.4, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-03T16:07:02", "normal": 1.5, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-03T20:10:25", "duration": 3600000, "extended": 2.2, @@ -20767,7 +20769,7 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-03T20:10:25", "duration": 3600000, "extended": 2.2, @@ -20775,57 +20777,60629 @@ var PlatformBolusSet = []map[string]interface{}{ "subType": "dual/square", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-04T05:00:38", "normal": 3.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-04T05:00:38", "normal": 3.55, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-04T12:35:17", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-04T12:35:17", "normal": 1.9, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-04T15:46:38", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-04T15:46:38", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-04T22:01:14", "normal": 4.2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-05T09:37:58", "normal": 2, "subType": "normal", }, { - "deviceId": "Some-Pump", + "deviceId": "some-other-pump", "deviceTime": "2018-11-05T13:19:18", "normal": 2, "subType": "normal", }, } + +var jfBasalStr = `[ + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T22:00:00", + "duration": 1217000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T22:20:17", + "duration": 800000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T22:33:37", + "duration": 5183000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T00:00:00", + "duration": 7992000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T02:13:12", + "duration": 2334000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T05:52:06", + "duration": 6987000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T07:48:33", + "duration": 1140000, + "percent": 0.4, + "rate": 0.62, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T07:48:33", + "duration": 1140000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-11-15T12:49:31Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T07:48:33", + "duration": 1109000, + "expectedDuration": 1140000, + "percent": 0.4, + "rate": 0.62, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T07:48:33", + "duration": 1140000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-11-15T12:49:31Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T08:07:02", + "duration": 2631000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T08:50:53", + "duration": 8779000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:17:12", + "duration": 1800000, + "percent": 0.6, + "rate": 0.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:17:12", + "duration": 1800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-15T16:18:10Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:47:12", + "duration": 592000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:57:04", + "duration": 7200000, + "percent": 0.35, + "rate": 0.5, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:57:04", + "duration": 7200000, + "rate": 1.43, + "scheduleName": "basal 3", + "time": "2017-11-15T16:58:02Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:57:04", + "duration": 176000, + "expectedDuration": 7200000, + "percent": 0.35, + "rate": 0.5, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:57:04", + "duration": 7200000, + "rate": 1.43, + "scheduleName": "basal 3", + "time": "2017-11-15T16:58:02Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T12:00:00", + "duration": 7200000, + "percent": 0.35, + "rate": 0.22, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T12:00:00", + "duration": 7200000, + "rate": 0.63, + "scheduleName": "basal 3", + "time": "2017-11-15T17:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T12:00:00", + "duration": 7024000, + "expectedDuration": 7200000, + "percent": 0.35, + "rate": 0.22, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T12:00:00", + "duration": 7200000, + "rate": 0.63, + "scheduleName": "basal 3", + "time": "2017-11-15T17:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T13:57:04", + "duration": 14576000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T08:30:00", + "duration": 3356000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T09:25:56", + "duration": 7200000, + "percent": 0.5, + "rate": 0.72, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T09:25:56", + "duration": 7200000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2017-11-16T14:26:54Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T11:25:56", + "duration": 2044000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T12:00:00", + "duration": 1425000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T12:23:45", + "duration": 5400000, + "percent": 0.5, + "rate": 0.32, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T12:23:45", + "duration": 5400000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2017-11-16T17:24:43Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T13:53:45", + "duration": 14775000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T00:00:00", + "duration": 2543000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T00:42:23", + "duration": 12600000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T00:42:23", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-17T05:43:21Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T00:42:23", + "duration": 10057000, + "expectedDuration": 12600000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T00:42:23", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-17T05:43:21Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T03:30:00", + "duration": 12600000, + "percent": 0.65, + "rate": 0.84, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T03:30:00", + "duration": 12600000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2017-11-17T08:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T03:30:00", + "duration": 2543000, + "expectedDuration": 12600000, + "percent": 0.65, + "rate": 0.84, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T03:30:00", + "duration": 12600000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2017-11-17T08:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T04:12:23", + "duration": 4657000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T08:30:00", + "duration": 10937000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T11:32:17", + "duration": 10800000, + "percent": 0.6, + "rate": 0.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T11:32:17", + "duration": 10800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-17T16:33:15Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T11:32:17", + "duration": 1663000, + "expectedDuration": 10800000, + "percent": 0.6, + "rate": 0.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T11:32:17", + "duration": 10800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-17T16:33:15Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T12:00:00", + "duration": 7860000, + "percent": 0.6, + "rate": 0.39, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T12:00:00", + "duration": 7860000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-11-17T17:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T12:00:00", + "duration": 6157000, + "expectedDuration": 7860000, + "percent": 0.6, + "rate": 0.39, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T12:00:00", + "duration": 7860000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-11-17T17:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T13:42:37", + "duration": 47000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T13:43:24", + "duration": 10800000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T13:43:24", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-11-17T18:44:22Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T16:43:24", + "duration": 4596000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T18:00:00", + "duration": 2896000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T18:48:16", + "duration": 4862000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T20:09:18", + "duration": 6642000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T00:00:00", + "duration": 10582000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T02:56:22", + "duration": 21600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T02:56:22", + "duration": 21600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-20T07:57:20Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T02:56:22", + "duration": 2018000, + "expectedDuration": 21600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T02:56:22", + "duration": 21600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-20T07:57:20Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T03:30:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T03:30:00", + "duration": 21600000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-11-20T08:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T03:30:00", + "duration": 7200000, + "expectedDuration": 21600000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T03:30:00", + "duration": 21600000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-11-20T08:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T05:30:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T05:30:00", + "duration": 21600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-11-20T10:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T05:30:00", + "duration": 10800000, + "expectedDuration": 21600000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T05:30:00", + "duration": 21600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-11-20T10:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T08:30:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T08:30:00", + "duration": 21600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-20T13:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T08:30:00", + "duration": 1582000, + "expectedDuration": 21600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T08:30:00", + "duration": 21600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-20T13:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T08:56:22", + "duration": 11018000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T12:00:00", + "duration": 7848000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T14:10:48", + "duration": 9000000, + "percent": 1.25, + "rate": 0.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T14:10:48", + "duration": 9000000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-11-20T19:11:46Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T16:40:48", + "duration": 4752000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T18:00:00", + "duration": 4786000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T19:19:46", + "duration": 492000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T19:27:58", + "duration": 9122000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T08:30:00", + "duration": 5770000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:06:10", + "duration": 1860000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:06:10", + "duration": 1860000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-22T15:07:08Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:06:10", + "duration": 1803000, + "expectedDuration": 1860000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:06:10", + "duration": 1860000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-22T15:07:08Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:36:13", + "duration": 13000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:36:26", + "duration": 3600000, + "percent": 1.15, + "rate": 1.66, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:36:26", + "duration": 3600000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2017-11-22T15:37:24Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T11:36:26", + "duration": 1414000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T12:00:00", + "duration": 19357000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T17:22:37", + "duration": 385000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T17:29:02", + "duration": 1858000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T12:00:00", + "duration": 499000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T12:08:19", + "duration": 9000000, + "percent": 0.55, + "rate": 0.35, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T12:08:19", + "duration": 9000000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2017-11-23T17:09:17Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T14:38:19", + "duration": 8117000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T16:53:36", + "duration": 5400000, + "percent": 1.5, + "rate": 0.97, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T16:53:36", + "duration": 5400000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-11-23T21:54:34Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T16:53:36", + "duration": 3984000, + "expectedDuration": 5400000, + "percent": 1.5, + "rate": 0.97, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T16:53:36", + "duration": 5400000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-11-23T21:54:34Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T18:00:00", + "duration": 5400000, + "percent": 1.5, + "rate": 1.72, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T18:00:00", + "duration": 5400000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2017-11-23T23:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T18:00:00", + "duration": 1416000, + "expectedDuration": 5400000, + "percent": 1.5, + "rate": 1.72, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T18:00:00", + "duration": 5400000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2017-11-23T23:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T18:23:36", + "duration": 12984000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T22:00:00", + "duration": 1335000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T22:22:15", + "duration": 7200000, + "percent": 0.7, + "rate": 0.91, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T22:22:15", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-11-24T03:23:13Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T22:22:15", + "duration": 5865000, + "expectedDuration": 7200000, + "percent": 0.7, + "rate": 0.91, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T22:22:15", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-11-24T03:23:13Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T00:00:00", + "duration": 7200000, + "percent": 0.7, + "rate": 1.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T00:00:00", + "duration": 7200000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2017-11-24T05:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T00:00:00", + "duration": 1335000, + "expectedDuration": 7200000, + "percent": 0.7, + "rate": 1.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T00:00:00", + "duration": 7200000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2017-11-24T05:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T00:22:15", + "duration": 5651000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T01:56:26", + "duration": 16200000, + "percent": 0.5, + "rate": 0.72, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T01:56:26", + "duration": 16200000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2017-11-24T06:57:24Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T01:56:26", + "duration": 5614000, + "expectedDuration": 16200000, + "percent": 0.5, + "rate": 0.72, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T01:56:26", + "duration": 16200000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2017-11-24T06:57:24Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:30:00", + "duration": 6360000, + "percent": 0.5, + "rate": 0.65, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:30:00", + "duration": 6360000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-11-24T08:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:30:00", + "duration": 713000, + "expectedDuration": 6360000, + "percent": 0.5, + "rate": 0.65, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:30:00", + "duration": 6360000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-11-24T08:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:41:53", + "duration": 14000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:42:07", + "duration": 480000, + "percent": 0.15000000000000002, + "rate": 0.19, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:42:07", + "duration": 480000, + "rate": 1.27, + "scheduleName": "basal 3", + "time": "2017-11-24T08:43:05Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:42:07", + "duration": 453000, + "expectedDuration": 480000, + "percent": 0.15000000000000002, + "rate": 0.19, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:42:07", + "duration": 480000, + "rate": 1.27, + "scheduleName": "basal 3", + "time": "2017-11-24T08:43:05Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:49:40", + "duration": 21000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:50:01", + "duration": 1260000, + "rate": 0 + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:50:01", + "duration": 1243000, + "expectedDuration": 1260000, + "rate": 0 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T04:10:44", + "duration": 17000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T04:11:01", + "duration": 25200000, + "percent": 0.30000000000000004, + "rate": 0.39, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T04:11:01", + "duration": 25200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-11-24T09:11:59Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T04:11:01", + "duration": 4739000, + "expectedDuration": 25200000, + "percent": 0.30000000000000004, + "rate": 0.39, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T04:11:01", + "duration": 25200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-11-24T09:11:59Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T05:30:00", + "duration": 25200000, + "percent": 0.30000000000000004, + "rate": 0.46, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T05:30:00", + "duration": 25200000, + "rate": 1.53, + "scheduleName": "basal 3", + "time": "2017-11-24T10:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T05:30:00", + "duration": 10800000, + "expectedDuration": 25200000, + "percent": 0.30000000000000004, + "rate": 0.46, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T05:30:00", + "duration": 25200000, + "rate": 1.53, + "scheduleName": "basal 3", + "time": "2017-11-24T10:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T08:30:00", + "duration": 21000000, + "percent": 0.30000000000000004, + "rate": 0.43, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T08:30:00", + "duration": 21000000, + "rate": 1.43, + "scheduleName": "basal 3", + "time": "2017-11-24T13:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T08:30:00", + "duration": 5443000, + "expectedDuration": 21000000, + "percent": 0.30000000000000004, + "rate": 0.43, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T08:30:00", + "duration": 21000000, + "rate": 1.43, + "scheduleName": "basal 3", + "time": "2017-11-24T13:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T10:00:43", + "duration": 7157000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T08:30:00", + "duration": 7831000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T10:40:31", + "duration": 3660000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T10:40:31", + "duration": 3660000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-25T15:41:29Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T10:40:31", + "duration": 3630000, + "expectedDuration": 3660000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T10:40:31", + "duration": 3660000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-25T15:41:29Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T11:41:01", + "duration": 26048000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T18:55:09", + "duration": 11091000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T08:30:00", + "duration": 4143000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T09:39:03", + "duration": 5400000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T09:39:03", + "duration": 5400000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-26T14:40:01Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T11:09:03", + "duration": 3057000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T12:00:00", + "duration": 11173000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T15:06:13", + "duration": 10800000, + "percent": 0.5, + "rate": 0.32, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T15:06:13", + "duration": 10800000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2017-11-27T20:07:11Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T15:06:13", + "duration": 10427000, + "expectedDuration": 10800000, + "percent": 0.5, + "rate": 0.32, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T15:06:13", + "duration": 10800000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2017-11-27T20:07:11Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T18:00:00", + "duration": 10800000, + "percent": 0.5, + "rate": 0.57, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T18:00:00", + "duration": 10800000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2017-11-27T23:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T18:00:00", + "duration": 373000, + "expectedDuration": 10800000, + "percent": 0.5, + "rate": 0.57, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T18:00:00", + "duration": 10800000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2017-11-27T23:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T18:06:13", + "duration": 14027000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T05:30:00", + "duration": 7330000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T07:32:10", + "duration": 8320000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T09:50:50", + "duration": 7750000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T12:00:00", + "duration": 13768000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T15:49:28", + "duration": 1919000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T13:21:27", + "duration": 16713000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T18:00:00", + "duration": 7752000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T20:09:12", + "duration": 4951000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T21:31:43", + "duration": 1697000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T05:30:00", + "duration": 2075000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T06:04:35", + "duration": 5400000, + "percent": 1.4, + "rate": 2.17, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T06:04:35", + "duration": 5400000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-12-01T14:05:33Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T07:34:35", + "duration": 3325000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T08:30:00", + "duration": 6166000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T10:12:46", + "duration": 5400000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T10:12:46", + "duration": 5400000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-01T18:13:44Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T11:42:46", + "duration": 1034000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T22:00:00", + "duration": 4345000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T23:12:25", + "duration": 1767000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T23:41:52", + "duration": 1088000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T05:30:00", + "duration": 7632000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T07:37:12", + "duration": 7359000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T09:39:51", + "duration": 8409000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T08:30:00", + "duration": 7692000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T10:38:12", + "duration": 1864000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T11:09:16", + "duration": 3044000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T18:00:00", + "duration": 11017000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T21:03:37", + "duration": 10800000, + "percent": 1.5, + "rate": 1.72, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T21:03:37", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2017-12-13T05:04:35Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T21:03:37", + "duration": 3383000, + "expectedDuration": 10800000, + "percent": 1.5, + "rate": 1.72, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T21:03:37", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2017-12-13T05:04:35Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T22:00:00", + "duration": 10800000, + "percent": 1.5, + "rate": 1.95, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T22:00:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-13T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T22:00:00", + "duration": 7200000, + "expectedDuration": 10800000, + "percent": 1.5, + "rate": 1.95, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T22:00:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-13T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T00:00:00", + "duration": 10800000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T00:00:00", + "duration": 10800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-13T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T00:00:00", + "duration": 217000, + "expectedDuration": 10800000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T00:00:00", + "duration": 10800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-13T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T00:03:37", + "duration": 12383000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T05:30:00", + "duration": 5676000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T07:04:36", + "duration": 7200000, + "percent": 0.4, + "rate": 0.62, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T07:04:36", + "duration": 7200000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-12-13T15:05:34Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T07:04:36", + "duration": 5124000, + "expectedDuration": 7200000, + "percent": 0.4, + "rate": 0.62, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T07:04:36", + "duration": 7200000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-12-13T15:05:34Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T08:30:00", + "duration": 7200000, + "percent": 0.4, + "rate": 0.58, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T08:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-13T16:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T08:30:00", + "duration": 2076000, + "expectedDuration": 7200000, + "percent": 0.4, + "rate": 0.58, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T08:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-13T16:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T09:04:36", + "duration": 8062000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T11:18:58", + "duration": 3600000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T11:18:58", + "duration": 3600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-13T19:19:56Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T11:18:58", + "duration": 2462000, + "expectedDuration": 3600000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T11:18:58", + "duration": 3600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-13T19:19:56Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T12:00:00", + "duration": 3600000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T12:00:00", + "duration": 3600000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-12-13T20:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T12:00:00", + "duration": 1138000, + "expectedDuration": 3600000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T12:00:00", + "duration": 3600000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-12-13T20:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T12:18:58", + "duration": 20462000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T18:00:00", + "duration": 3789000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T19:03:09", + "duration": 4406000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T20:16:35", + "duration": 6205000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T12:00:00", + "duration": 21479000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T17:57:59", + "duration": 7200000, + "percent": 1.45, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T17:57:59", + "duration": 7200000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-12-16T01:58:57Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T17:57:59", + "duration": 121000, + "expectedDuration": 7200000, + "percent": 1.45, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T17:57:59", + "duration": 7200000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-12-16T01:58:57Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T18:00:00", + "duration": 7200000, + "percent": 1.45, + "rate": 1.66, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T18:00:00", + "duration": 7200000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2017-12-16T02:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T18:00:00", + "duration": 7079000, + "expectedDuration": 7200000, + "percent": 1.45, + "rate": 1.66, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T18:00:00", + "duration": 7200000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2017-12-16T02:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T19:57:59", + "duration": 7321000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T03:30:00", + "duration": 6942000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:25:42", + "duration": 5400000, + "percent": 1.5, + "rate": 1.95, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:25:42", + "duration": 5400000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-16T13:26:40Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:25:42", + "duration": 258000, + "expectedDuration": 5400000, + "percent": 1.5, + "rate": 1.95, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:25:42", + "duration": 5400000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-16T13:26:40Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:30:00", + "duration": 5400000, + "percent": 1.5, + "rate": 2.32, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:30:00", + "duration": 5400000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-12-16T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:30:00", + "duration": 5142000, + "expectedDuration": 5400000, + "percent": 1.5, + "rate": 2.32, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:30:00", + "duration": 5400000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-12-16T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T06:55:42", + "duration": 5658000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T18:00:00", + "duration": 12497000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T21:28:17", + "duration": 2135000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T22:03:52", + "duration": 6968000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T00:00:00", + "duration": 4032000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T01:07:12", + "duration": 7200000, + "percent": 1.75, + "rate": 2.53, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T01:07:12", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-17T09:08:10Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T03:07:12", + "duration": 1368000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T22:00:00", + "duration": 4835000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T23:20:35", + "duration": 5400000, + "percent": 1.5, + "rate": 1.95, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T23:20:35", + "duration": 5400000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-19T07:21:33Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T23:20:35", + "duration": 2365000, + "expectedDuration": 5400000, + "percent": 1.5, + "rate": 1.95, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T23:20:35", + "duration": 5400000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-19T07:21:33Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T00:00:00", + "duration": 5400000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T00:00:00", + "duration": 5400000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-19T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T00:00:00", + "duration": 3035000, + "expectedDuration": 5400000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T00:00:00", + "duration": 5400000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-19T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T00:50:35", + "duration": 9565000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T05:30:00", + "duration": 1701000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T05:58:21", + "duration": 50296000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T19:56:37", + "duration": 7403000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T18:00:00", + "duration": 8649000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T20:24:09", + "duration": 9000000, + "percent": 1.95, + "rate": 2.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T20:24:09", + "duration": 9000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2017-12-23T04:25:07Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T20:24:09", + "duration": 5751000, + "expectedDuration": 9000000, + "percent": 1.95, + "rate": 2.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T20:24:09", + "duration": 9000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2017-12-23T04:25:07Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T22:00:00", + "duration": 9000000, + "percent": 1.95, + "rate": 2.53, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T22:00:00", + "duration": 9000000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-23T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T22:00:00", + "duration": 3249000, + "expectedDuration": 9000000, + "percent": 1.95, + "rate": 2.53, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T22:00:00", + "duration": 9000000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-23T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T22:54:09", + "duration": 3951000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T18:00:00", + "duration": 366000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T18:06:06", + "duration": 613000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T18:16:19", + "duration": 13421000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T03:30:00", + "duration": 5480000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:01:20", + "duration": 12600000, + "percent": 1.6, + "rate": 2.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:01:20", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-25T13:02:18Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:01:20", + "duration": 1720000, + "expectedDuration": 12600000, + "percent": 1.6, + "rate": 2.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:01:20", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-25T13:02:18Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:30:00", + "duration": 12600000, + "percent": 1.6, + "rate": 2.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:30:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-12-25T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:30:00", + "duration": 10800000, + "expectedDuration": 12600000, + "percent": 1.6, + "rate": 2.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:30:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-12-25T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T08:30:00", + "duration": 12600000, + "percent": 1.6, + "rate": 2.32, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-25T16:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T08:30:00", + "duration": 80000, + "expectedDuration": 12600000, + "percent": 1.6, + "rate": 2.32, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-25T16:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T08:31:20", + "duration": 12520000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T05:30:00", + "duration": 3692000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T06:31:32", + "duration": 14400000, + "percent": 1.65, + "rate": 2.55, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T06:31:32", + "duration": 14400000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-12-26T14:32:30Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T06:31:32", + "duration": 7108000, + "expectedDuration": 14400000, + "percent": 1.65, + "rate": 2.55, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T06:31:32", + "duration": 14400000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-12-26T14:32:30Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T08:30:00", + "duration": 14400000, + "percent": 1.65, + "rate": 2.39, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T08:30:00", + "duration": 14400000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-26T16:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T08:30:00", + "duration": 7292000, + "expectedDuration": 14400000, + "percent": 1.65, + "rate": 2.39, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T08:30:00", + "duration": 14400000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-26T16:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T10:31:32", + "duration": 5308000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T18:00:00", + "duration": 9007000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T20:30:07", + "duration": 4826000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T21:50:33", + "duration": 567000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T12:00:00", + "duration": 175000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T12:02:55", + "duration": 203000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T12:06:18", + "duration": 21222000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T22:00:00", + "duration": 5252000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T23:27:32", + "duration": 7200000, + "percent": 1.45, + "rate": 1.88, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T23:27:32", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-31T07:28:30Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T23:27:32", + "duration": 1948000, + "expectedDuration": 7200000, + "percent": 1.45, + "rate": 1.88, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T23:27:32", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-31T07:28:30Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T00:00:00", + "duration": 7200000, + "percent": 1.45, + "rate": 2.1, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T00:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-31T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T00:00:00", + "duration": 5252000, + "expectedDuration": 7200000, + "percent": 1.45, + "rate": 2.1, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T00:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-31T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T01:27:32", + "duration": 7348000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T05:30:00", + "duration": 10163000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T08:19:23", + "duration": 227000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T08:23:10", + "duration": 410000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T08:30:00", + "duration": 1916000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T09:01:56", + "duration": 291000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T09:06:47", + "duration": 10393000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T00:00:00", + "duration": 2058000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T00:34:18", + "duration": 18000000, + "percent": 1.3, + "rate": 1.88, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T00:34:18", + "duration": 18000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-01-05T08:35:16Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T00:34:18", + "duration": 10542000, + "expectedDuration": 18000000, + "percent": 1.3, + "rate": 1.88, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T00:34:18", + "duration": 18000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-01-05T08:35:16Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T03:30:00", + "duration": 18000000, + "percent": 1.3, + "rate": 1.69, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T03:30:00", + "duration": 18000000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-01-05T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T03:30:00", + "duration": 7200000, + "expectedDuration": 18000000, + "percent": 1.3, + "rate": 1.69, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T03:30:00", + "duration": 18000000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-01-05T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T05:30:00", + "duration": 18000000, + "percent": 1.3, + "rate": 2.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T05:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-01-05T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T05:30:00", + "duration": 258000, + "expectedDuration": 18000000, + "percent": 1.3, + "rate": 2.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T05:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-01-05T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T05:34:18", + "duration": 10542000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T00:00:00", + "duration": 5352000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T01:29:12", + "duration": 16200000, + "percent": 1.45, + "rate": 2.1, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T01:29:12", + "duration": 16200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-01-06T09:30:10Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T01:29:12", + "duration": 7248000, + "expectedDuration": 16200000, + "percent": 1.45, + "rate": 2.1, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T01:29:12", + "duration": 16200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-01-06T09:30:10Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T03:30:00", + "duration": 16200000, + "percent": 1.45, + "rate": 1.88, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T03:30:00", + "duration": 16200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-01-06T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T03:30:00", + "duration": 7200000, + "expectedDuration": 16200000, + "percent": 1.45, + "rate": 1.88, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T03:30:00", + "duration": 16200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-01-06T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T05:30:00", + "duration": 16200000, + "percent": 1.45, + "rate": 2.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T05:30:00", + "duration": 16200000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-01-06T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T05:30:00", + "duration": 1752000, + "expectedDuration": 16200000, + "percent": 1.45, + "rate": 2.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T05:30:00", + "duration": 16200000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-01-06T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T05:59:12", + "duration": 9048000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T08:30:00", + "duration": 10301000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T11:21:41", + "duration": 1674000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T11:49:35", + "duration": 625000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T12:00:00", + "duration": 10354000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T14:52:34", + "duration": 729000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T15:04:43", + "duration": 10517000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T05:30:00", + "duration": 6107000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T07:11:47", + "duration": 3600000, + "percent": 0.35, + "rate": 0.54, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T07:11:47", + "duration": 3600000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-01-10T15:12:45Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T08:11:47", + "duration": 1093000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T08:30:00", + "duration": 5259000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T09:57:39", + "duration": 54000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T09:58:33", + "duration": 7287000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T22:00:00", + "duration": 4793000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T23:19:53", + "duration": 5171000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T00:46:04", + "duration": 9836000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T12:00:00", + "duration": 19060000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T17:17:40", + "duration": 298000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T17:22:38", + "duration": 2242000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T18:00:00", + "duration": 762000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T18:12:42", + "duration": 364000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T18:18:46", + "duration": 13274000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T08:30:00", + "duration": 3806000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T09:33:26", + "duration": 32400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T09:33:26", + "duration": 32400000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-01-19T17:34:24Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T09:33:26", + "duration": 8794000, + "expectedDuration": 32400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T09:33:26", + "duration": 32400000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-01-19T17:34:24Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T12:00:00", + "duration": 32400000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T12:00:00", + "duration": 32400000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-01-19T20:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T12:00:00", + "duration": 21600000, + "expectedDuration": 32400000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T12:00:00", + "duration": 32400000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-01-19T20:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T18:00:00", + "duration": 32400000, + "percent": 0.75, + "rate": 0.86, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T18:00:00", + "duration": 32400000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-01-20T02:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T18:00:00", + "duration": 2006000, + "expectedDuration": 32400000, + "percent": 0.75, + "rate": 0.86, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T18:00:00", + "duration": 32400000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-01-20T02:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T18:33:26", + "duration": 12394000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T08:30:00", + "duration": 12207000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T11:53:27", + "duration": 10800000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T11:53:27", + "duration": 10800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-01-20T19:54:25Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T11:53:27", + "duration": 393000, + "expectedDuration": 10800000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T11:53:27", + "duration": 10800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-01-20T19:54:25Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T12:00:00", + "duration": 10800000, + "percent": 0.65, + "rate": 0.42, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T12:00:00", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-01-20T20:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T12:00:00", + "duration": 10407000, + "expectedDuration": 10800000, + "percent": 0.65, + "rate": 0.42, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T12:00:00", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-01-20T20:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T14:53:27", + "duration": 11193000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T00:00:00", + "duration": 4261000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T01:11:01", + "duration": 404000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T01:17:45", + "duration": 7935000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T08:30:00", + "duration": 1757000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T08:59:17", + "duration": 695000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T09:10:52", + "duration": 10148000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T12:00:00", + "duration": 18043000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T17:00:43", + "duration": 2404000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T17:40:47", + "duration": 1153000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T00:00:00", + "duration": 4572000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T01:16:12", + "duration": 303000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T01:21:15", + "duration": 7725000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T08:30:00", + "duration": 1219000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T08:50:19", + "duration": 5400000, + "percent": 1.3, + "rate": 1.88, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T08:50:19", + "duration": 5400000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-01-31T16:51:17Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T10:20:19", + "duration": 5981000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T12:00:00", + "duration": 14758000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T16:05:58", + "duration": 375000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T16:12:13", + "duration": 6467000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T18:00:00", + "duration": 11599000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T21:13:19", + "duration": 711000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T21:25:10", + "duration": 2090000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T18:00:00", + "duration": 10305000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T20:51:45", + "duration": 7200000, + "percent": 0.19999999999999996, + "rate": 0.23, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T20:51:45", + "duration": 7200000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-02-04T04:52:43Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T20:51:45", + "duration": 4095000, + "expectedDuration": 7200000, + "percent": 0.19999999999999996, + "rate": 0.23, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T20:51:45", + "duration": 7200000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-02-04T04:52:43Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T22:00:00", + "duration": 7200000, + "percent": 0.19999999999999996, + "rate": 0.28, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-02-04T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T22:00:00", + "duration": 3105000, + "expectedDuration": 7200000, + "percent": 0.19999999999999996, + "rate": 0.28, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-02-04T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T22:51:45", + "duration": 4095000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T12:00:00", + "duration": 19370000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T17:22:50", + "duration": 3600000, + "percent": 0.7, + "rate": 0.45, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T17:22:50", + "duration": 3600000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-02-06T01:23:48Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T17:22:50", + "duration": 2230000, + "expectedDuration": 3600000, + "percent": 0.7, + "rate": 0.45, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T17:22:50", + "duration": 3600000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-02-06T01:23:48Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T18:00:00", + "duration": 3600000, + "percent": 0.7, + "rate": 0.8, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T18:00:00", + "duration": 3600000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-02-06T02:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T18:00:00", + "duration": 1370000, + "expectedDuration": 3600000, + "percent": 0.7, + "rate": 0.8, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T18:00:00", + "duration": 3600000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-02-06T02:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T18:22:50", + "duration": 13030000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T03:30:00", + "duration": 7580000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T05:36:20", + "duration": 249000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T05:40:29", + "duration": 10171000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T08:30:00", + "duration": 169000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T08:32:49", + "duration": 544000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T08:41:53", + "duration": 11887000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T12:00:00", + "duration": 16275000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T16:31:15", + "duration": 455000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T16:38:50", + "duration": 4870000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T18:00:00", + "duration": 13413000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T21:43:33", + "duration": 246000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T21:47:39", + "duration": 741000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:00:00", + "duration": 643000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:10:43", + "duration": 60000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:10:43", + "duration": 60000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-15T08:11:41Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:10:43", + "duration": 7000, + "expectedDuration": 60000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:10:43", + "duration": 60000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-15T08:11:41Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:10:50", + "duration": 273000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:15:23", + "duration": 28000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:15:51", + "duration": 7200000, + "percent": 1.3, + "rate": 1.95, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:15:51", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-15T08:16:49Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T02:15:51", + "duration": 4449000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T00:00:00", + "duration": 10840000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:00:40", + "duration": 10800000, + "percent": 1.45, + "rate": 2.17, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:00:40", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-16T11:01:38Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:00:40", + "duration": 1760000, + "expectedDuration": 10800000, + "percent": 1.45, + "rate": 2.17, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:00:40", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-16T11:01:38Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:30:00", + "duration": 10800000, + "percent": 1.45, + "rate": 1.95, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:30:00", + "duration": 10800000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-02-16T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:30:00", + "duration": 7200000, + "expectedDuration": 10800000, + "percent": 1.45, + "rate": 1.95, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:30:00", + "duration": 10800000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-02-16T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T05:30:00", + "duration": 10800000, + "percent": 1.45, + "rate": 2.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T05:30:00", + "duration": 10800000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-02-16T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T05:30:00", + "duration": 1840000, + "expectedDuration": 10800000, + "percent": 1.45, + "rate": 2.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T05:30:00", + "duration": 10800000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-02-16T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T06:00:40", + "duration": 8960000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T05:30:00", + "duration": 9662000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T08:11:02", + "duration": 6831000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T10:04:53", + "duration": 973000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T10:21:06", + "duration": 97000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T10:22:43", + "duration": 5837000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T12:00:00", + "duration": 4664000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T13:17:44", + "duration": 7380000, + "percent": 1.5, + "rate": 0.97, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T13:17:44", + "duration": 7380000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-02-18T21:18:42Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T13:17:44", + "duration": 7325000, + "expectedDuration": 7380000, + "percent": 1.5, + "rate": 0.97, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T13:17:44", + "duration": 7380000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-02-18T21:18:42Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T15:19:49", + "duration": 9611000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T22:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T22:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T22:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T05:30:00", + "duration": 7957000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T07:42:37", + "duration": 35000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T07:43:12", + "duration": 2808000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T08:30:00", + "duration": 8781000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T10:56:21", + "duration": 254000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T11:00:35", + "duration": 3565000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T00:00:00", + "duration": 4542000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T01:15:42", + "duration": 10800000, + "percent": 0.7, + "rate": 1.05, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T01:15:42", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-22T09:16:40Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T01:15:42", + "duration": 8058000, + "expectedDuration": 10800000, + "percent": 0.7, + "rate": 1.05, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T01:15:42", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-22T09:16:40Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T03:30:00", + "duration": 10800000, + "percent": 0.7, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T03:30:00", + "duration": 10800000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-02-22T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T03:30:00", + "duration": 2742000, + "expectedDuration": 10800000, + "percent": 0.7, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T03:30:00", + "duration": 10800000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-02-22T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T04:15:42", + "duration": 4458000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T18:00:00", + "duration": 366000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T18:06:06", + "duration": 21600000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T18:06:06", + "duration": 21600000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-02-23T02:07:04Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T18:06:06", + "duration": 14034000, + "expectedDuration": 21600000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T18:06:06", + "duration": 21600000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-02-23T02:07:04Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T22:00:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T22:00:00", + "duration": 21600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-02-23T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T22:00:00", + "duration": 7200000, + "expectedDuration": 21600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T22:00:00", + "duration": 21600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-02-23T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T00:00:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T00:00:00", + "duration": 21600000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-23T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T00:00:00", + "duration": 366000, + "expectedDuration": 21600000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T00:00:00", + "duration": 21600000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-23T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T00:06:06", + "duration": 9204000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T02:39:30", + "duration": 18000000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T02:39:30", + "duration": 18000000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-23T10:40:28Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T02:39:30", + "duration": 3030000, + "expectedDuration": 18000000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T02:39:30", + "duration": 18000000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-23T10:40:28Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T03:30:00", + "duration": 18000000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T03:30:00", + "duration": 18000000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-02-23T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T03:30:00", + "duration": 7200000, + "expectedDuration": 18000000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T03:30:00", + "duration": 18000000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-02-23T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T05:30:00", + "duration": 18000000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T05:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-02-23T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T05:30:00", + "duration": 7770000, + "expectedDuration": 18000000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T05:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-02-23T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T07:39:30", + "duration": 3030000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T08:30:00", + "duration": 8164000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T10:46:04", + "duration": 18000000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T10:46:04", + "duration": 18000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-02-23T18:47:02Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T10:46:04", + "duration": 4436000, + "expectedDuration": 18000000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T10:46:04", + "duration": 18000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-02-23T18:47:02Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T12:00:00", + "duration": 18000000, + "percent": 0.65, + "rate": 0.42, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T12:00:00", + "duration": 18000000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-02-23T20:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T12:00:00", + "duration": 13564000, + "expectedDuration": 18000000, + "percent": 0.65, + "rate": 0.42, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T12:00:00", + "duration": 18000000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-02-23T20:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T15:46:04", + "duration": 8036000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T12:00:00", + "duration": 21410000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T17:56:50", + "duration": 2163000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T18:32:53", + "duration": 12427000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T22:00:00", + "duration": 5415000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T23:30:15", + "duration": 7200000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T23:30:15", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-02-26T07:31:13Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T23:30:15", + "duration": 1785000, + "expectedDuration": 7200000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T23:30:15", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-02-26T07:31:13Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T00:00:00", + "duration": 7200000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T00:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-26T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T00:00:00", + "duration": 5415000, + "expectedDuration": 7200000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T00:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-26T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T01:30:15", + "duration": 7185000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T08:30:00", + "duration": 345000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T08:35:45", + "duration": 5400000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T08:35:45", + "duration": 5400000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-02-27T16:36:43Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T10:05:45", + "duration": 6855000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T18:00:00", + "duration": 9705000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T20:41:45", + "duration": 7200000, + "percent": 1.3, + "rate": 1.49, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T20:41:45", + "duration": 7200000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-02-28T04:42:43Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T20:41:45", + "duration": 4695000, + "expectedDuration": 7200000, + "percent": 1.3, + "rate": 1.49, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T20:41:45", + "duration": 7200000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-02-28T04:42:43Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T22:00:00", + "duration": 7200000, + "percent": 1.3, + "rate": 1.88, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-02-28T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T22:00:00", + "duration": 2505000, + "expectedDuration": 7200000, + "percent": 1.3, + "rate": 1.88, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-02-28T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T22:41:45", + "duration": 4695000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T00:00:00", + "duration": 5211000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T01:26:51", + "duration": 199000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T01:30:10", + "duration": 147000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T01:32:37", + "duration": 12600000, + "percent": 0.75, + "rate": 1.12, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T01:32:37", + "duration": 12600000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-02-28T09:33:35Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T01:32:37", + "duration": 7043000, + "expectedDuration": 12600000, + "percent": 0.75, + "rate": 1.12, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T01:32:37", + "duration": 12600000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-02-28T09:33:35Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T03:30:00", + "duration": 12600000, + "percent": 0.75, + "rate": 1.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T03:30:00", + "duration": 12600000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-02-28T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T03:30:00", + "duration": 5557000, + "expectedDuration": 12600000, + "percent": 0.75, + "rate": 1.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T03:30:00", + "duration": 12600000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-02-28T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T05:02:37", + "duration": 1643000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T12:00:00", + "duration": 91000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T12:01:31", + "duration": 7200000, + "percent": 1.35, + "rate": 0.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T12:01:31", + "duration": 7200000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-03-02T20:02:29Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T14:01:31", + "duration": 14309000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T00:00:00", + "duration": 8771000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T02:26:11", + "duration": 272000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T02:30:43", + "duration": 3557000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T08:30:00", + "duration": 5906000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T10:08:26", + "duration": 2274000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T10:46:20", + "duration": 4420000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T18:00:00", + "duration": 2434000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T18:40:34", + "duration": 3332000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T19:36:06", + "duration": 8634000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T22:00:00", + "duration": 7042000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T23:57:22", + "duration": 114000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T23:59:16", + "duration": 44000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T08:30:00", + "duration": 135000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T08:32:15", + "duration": 360000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T09:38:15", + "duration": 8505000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T00:00:00", + "duration": 5721000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T01:35:21", + "duration": 660000, + "percent": 0.6, + "rate": 0.9, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T01:35:21", + "duration": 660000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-03-14T08:36:19Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T01:35:21", + "duration": 638000, + "expectedDuration": 660000, + "percent": 0.6, + "rate": 0.9, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T01:35:21", + "duration": 660000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-03-14T08:36:19Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T01:45:59", + "duration": 6241000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T18:00:00", + "duration": 12763000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T21:32:43", + "duration": 200000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T21:36:03", + "duration": 1437000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T00:00:00", + "duration": 7717000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T02:08:37", + "duration": 9000000, + "percent": 1.2, + "rate": 1.8, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T02:08:37", + "duration": 9000000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-03-16T09:09:35Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T02:08:37", + "duration": 4883000, + "expectedDuration": 9000000, + "percent": 1.2, + "rate": 1.8, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T02:08:37", + "duration": 9000000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-03-16T09:09:35Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T03:30:00", + "duration": 9000000, + "percent": 1.2, + "rate": 1.62, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T03:30:00", + "duration": 9000000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-03-16T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T03:30:00", + "duration": 4117000, + "expectedDuration": 9000000, + "percent": 1.2, + "rate": 1.62, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T03:30:00", + "duration": 9000000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-03-16T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T04:38:37", + "duration": 3083000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T00:00:00", + "duration": 1387000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T00:23:07", + "duration": 5575000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T01:56:02", + "duration": 5638000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T00:00:00", + "duration": 5074000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T01:24:34", + "duration": 3600000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T01:24:34", + "duration": 3600000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-03-20T08:25:32Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T02:24:34", + "duration": 3926000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T12:00:00", + "duration": 14636000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T16:03:56", + "duration": 156000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T16:06:32", + "duration": 6808000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T12:00:00", + "duration": 261000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T12:04:21", + "duration": 241000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T12:08:22", + "duration": 21098000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T08:30:00", + "duration": 5750000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T10:05:50", + "duration": 188000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T10:08:58", + "duration": 6662000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T12:00:00", + "duration": 17191000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T16:46:31", + "duration": 4727000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T18:05:18", + "duration": 14082000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T18:00:00", + "duration": 2581000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T18:43:01", + "duration": 67000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T21:44:08", + "duration": 952000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T18:00:00", + "duration": 9738000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T20:42:18", + "duration": 1004000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T20:59:02", + "duration": 3658000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T00:00:00", + "duration": 12403000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:26:43", + "duration": 7200000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:26:43", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-03-30T07:27:41Z", + "timezoneOffset": -180, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:26:43", + "duration": 197000, + "expectedDuration": 7200000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:26:43", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-03-30T07:27:41Z", + "timezoneOffset": -180, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:30:00", + "duration": 7200000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-03-30T07:30:58Z", + "timezoneOffset": -180, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:30:00", + "duration": 7003000, + "expectedDuration": 7200000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-03-30T07:30:58Z", + "timezoneOffset": -180, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T05:26:43", + "duration": 197000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T18:00:00", + "duration": 3804000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T19:03:24", + "duration": 476000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T19:11:20", + "duration": 10120000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T08:30:00", + "duration": 3078000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T09:21:18", + "duration": 5400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T09:21:18", + "duration": 5400000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-04-03T13:22:16Z", + "timezoneOffset": -180, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T10:51:18", + "duration": 4122000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T18:00:00", + "duration": 8562000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T20:22:42", + "duration": 87000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T17:24:09", + "duration": 2151000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T18:00:00", + "duration": 10423000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T20:53:43", + "duration": 2326000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T21:32:29", + "duration": 1651000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T08:30:00", + "duration": 11164000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T11:36:04", + "duration": 7381000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T13:39:05", + "duration": 15655000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T18:00:00", + "duration": 6679000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T19:51:19", + "duration": 1653000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T20:18:52", + "duration": 6068000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T08:30:00", + "duration": 6131000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T10:12:11", + "duration": 1800000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T10:12:11", + "duration": 1800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-04-10T17:13:09Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T10:42:11", + "duration": 4669000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T12:00:00", + "duration": 243000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T12:04:03", + "duration": 36000000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T12:04:03", + "duration": 36000000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-04-11T19:05:01Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T12:04:03", + "duration": 21357000, + "expectedDuration": 36000000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T12:04:03", + "duration": 36000000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-04-11T19:05:01Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T18:00:00", + "duration": 36000000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T18:00:00", + "duration": 36000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-04-12T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T18:00:00", + "duration": 14400000, + "expectedDuration": 36000000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T18:00:00", + "duration": 36000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-04-12T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T22:00:00", + "duration": 36000000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T22:00:00", + "duration": 36000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-04-12T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T22:00:00", + "duration": 242000, + "expectedDuration": 36000000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T22:00:00", + "duration": 36000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-04-12T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T22:04:02", + "duration": 6958000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T08:30:00", + "duration": 321000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T08:35:21", + "duration": 28800000, + "percent": 0.7, + "rate": 1.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T08:35:21", + "duration": 28800000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-04-12T15:36:19Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T08:35:21", + "duration": 12279000, + "expectedDuration": 28800000, + "percent": 0.7, + "rate": 1.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T08:35:21", + "duration": 28800000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-04-12T15:36:19Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T12:00:00", + "duration": 28200000, + "percent": 0.7, + "rate": 0.45, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T12:00:00", + "duration": 28200000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-04-12T19:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T12:00:00", + "duration": 15906000, + "expectedDuration": 28200000, + "percent": 0.7, + "rate": 0.45, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T12:00:00", + "duration": 28200000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-04-12T19:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T16:25:06", + "duration": 17000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T16:25:23", + "duration": 12600000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T16:25:23", + "duration": 12600000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-04-12T23:26:21Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T16:25:23", + "duration": 5677000, + "expectedDuration": 12600000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T16:25:23", + "duration": 12600000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-04-12T23:26:21Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T18:00:00", + "duration": 12600000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T18:00:00", + "duration": 12600000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-04-13T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T18:00:00", + "duration": 6923000, + "expectedDuration": 12600000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T18:00:00", + "duration": 12600000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-04-13T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T19:55:23", + "duration": 7477000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T22:00:00", + "duration": 5512000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T23:31:52", + "duration": 351000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T23:37:43", + "duration": 562000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T23:47:05", + "duration": 36000000, + "percent": 0.6, + "rate": 0.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T23:47:05", + "duration": 36000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-04-13T06:48:03Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T23:47:05", + "duration": 775000, + "expectedDuration": 36000000, + "percent": 0.6, + "rate": 0.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T23:47:05", + "duration": 36000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-04-13T06:48:03Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:00:00", + "duration": 840000, + "percent": 0.6, + "rate": 0.9, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:00:00", + "duration": 840000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-04-13T07:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:00:00", + "duration": 62000, + "expectedDuration": 840000, + "percent": 0.6, + "rate": 0.9, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:00:00", + "duration": 840000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-04-13T07:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:01:02", + "duration": 13000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:01:15", + "duration": 10380000, + "percent": 0.5, + "rate": 0.75, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:01:15", + "duration": 10380000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-04-13T07:02:13Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:01:15", + "duration": 10367000, + "expectedDuration": 10380000, + "percent": 0.5, + "rate": 0.75, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:01:15", + "duration": 10380000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-04-13T07:02:13Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T02:54:02", + "duration": 17000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T02:54:19", + "duration": 27000000, + "percent": 0.35, + "rate": 0.52, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T02:54:19", + "duration": 27000000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-04-13T09:55:17Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T02:54:19", + "duration": 2141000, + "expectedDuration": 27000000, + "percent": 0.35, + "rate": 0.52, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T02:54:19", + "duration": 27000000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-04-13T09:55:17Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T03:30:00", + "duration": 27000000, + "percent": 0.35, + "rate": 0.47, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T03:30:00", + "duration": 27000000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-04-13T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T03:30:00", + "duration": 7200000, + "expectedDuration": 27000000, + "percent": 0.35, + "rate": 0.47, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T03:30:00", + "duration": 27000000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-04-13T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T05:30:00", + "duration": 14700000, + "percent": 0.35, + "rate": 0.54, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T05:30:00", + "duration": 14700000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-04-13T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T05:30:00", + "duration": 5354000, + "expectedDuration": 14700000, + "percent": 0.35, + "rate": 0.54, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T05:30:00", + "duration": 14700000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-04-13T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T06:59:14", + "duration": 5446000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T08:30:00", + "duration": 1684000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T08:58:04", + "duration": 3600000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T08:58:04", + "duration": 3600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-04-13T15:59:02Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T09:58:04", + "duration": 211000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T10:01:35", + "duration": 3600000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T10:01:35", + "duration": 3600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-04-13T17:02:33Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T11:01:35", + "duration": 3505000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T12:00:00", + "duration": 1514000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T12:25:14", + "duration": 12840000, + "percent": 0.55, + "rate": 0.35, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T12:25:14", + "duration": 12840000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-04-13T19:26:12Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T12:25:14", + "duration": 12810000, + "expectedDuration": 12840000, + "percent": 0.55, + "rate": 0.35, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T12:25:14", + "duration": 12840000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-04-13T19:26:12Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T15:58:44", + "duration": 8000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T15:58:52", + "duration": 5400000, + "percent": 1.25, + "rate": 0.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T15:58:52", + "duration": 5400000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-04-13T22:59:50Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T17:28:52", + "duration": 1868000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T18:00:00", + "duration": 4291000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T19:11:31", + "duration": 60000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T19:11:31", + "duration": 60000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-04-14T02:12:29Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T19:11:31", + "duration": 48000, + "expectedDuration": 60000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T19:11:31", + "duration": 60000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-04-14T02:12:29Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T19:12:19", + "duration": 10061000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T00:00:00", + "duration": 2499000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T00:41:39", + "duration": 7200000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T00:41:39", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-04-14T07:42:37Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T02:41:39", + "duration": 2901000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T05:30:00", + "duration": 10759000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T08:29:19", + "duration": 4125000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T09:38:04", + "duration": 8516000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T12:00:00", + "duration": 4493000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T13:14:53", + "duration": 3600000, + "percent": 0.9, + "rate": 0.58, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T13:14:53", + "duration": 3600000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-04-14T20:15:51Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T14:14:53", + "duration": 13507000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T05:30:00", + "duration": 8560000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T07:52:40", + "duration": 8961000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T10:22:01", + "duration": 5879000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T22:00:00", + "duration": 6208000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T23:43:28", + "duration": 7200000, + "percent": 1.1, + "rate": 1.59, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T23:43:28", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-04-18T06:44:26Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T23:43:28", + "duration": 992000, + "expectedDuration": 7200000, + "percent": 1.1, + "rate": 1.59, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T23:43:28", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-04-18T06:44:26Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T00:00:00", + "duration": 7200000, + "percent": 1.1, + "rate": 1.65, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T00:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-04-18T07:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T00:00:00", + "duration": 6208000, + "expectedDuration": 7200000, + "percent": 1.1, + "rate": 1.65, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T00:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-04-18T07:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T01:43:28", + "duration": 6392000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T12:00:00", + "duration": 11187000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T15:06:27", + "duration": 3600000, + "percent": 0.7, + "rate": 0.45, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T15:06:27", + "duration": 3600000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-04-18T22:07:25Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T16:06:27", + "duration": 6813000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T08:30:00", + "duration": 7374000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T10:32:54", + "duration": 790000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T10:46:04", + "duration": 4436000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T05:30:00", + "duration": 10425000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T08:23:45", + "duration": 375000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T12:00:00", + "duration": 10788000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T14:59:48", + "duration": 3678000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T16:01:06", + "duration": 7134000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T12:00:00", + "duration": 9679000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T14:41:19", + "duration": 10800000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T14:41:19", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-04-22T21:42:17Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T17:41:19", + "duration": 1121000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T22:00:00", + "duration": 4227000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T23:10:27", + "duration": 586000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T23:20:13", + "duration": 2387000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T18:00:00", + "duration": 13412000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T21:43:32", + "duration": 200000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T21:46:52", + "duration": 788000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T00:00:00", + "duration": 3746000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:02:26", + "duration": 180000, + "percent": 0.7, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:02:26", + "duration": 180000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-04-26T08:03:24Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:02:26", + "duration": 128000, + "expectedDuration": 180000, + "percent": 0.7, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:02:26", + "duration": 180000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-04-26T08:03:24Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:04:34", + "duration": 11000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:04:45", + "duration": 18000000, + "percent": 0.85, + "rate": 1.31, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:04:45", + "duration": 18000000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-04-26T08:05:43Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:04:45", + "duration": 8715000, + "expectedDuration": 18000000, + "percent": 0.85, + "rate": 1.31, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:04:45", + "duration": 18000000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-04-26T08:05:43Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T03:30:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.19, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T03:30:00", + "duration": 18000000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-04-26T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T03:30:00", + "duration": 7200000, + "expectedDuration": 18000000, + "percent": 0.85, + "rate": 1.19, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T03:30:00", + "duration": 18000000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-04-26T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T05:30:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.36, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T05:30:00", + "duration": 18000000, + "rate": 1.6, + "scheduleName": "basal 3", + "time": "2018-04-26T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T05:30:00", + "duration": 2085000, + "expectedDuration": 18000000, + "percent": 0.85, + "rate": 1.36, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T05:30:00", + "duration": 18000000, + "rate": 1.6, + "scheduleName": "basal 3", + "time": "2018-04-26T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T06:04:45", + "duration": 8715000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T00:00:00", + "duration": 10498000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T02:54:58", + "duration": 21600000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T02:54:58", + "duration": 21600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-04-27T09:55:56Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T02:54:58", + "duration": 2102000, + "expectedDuration": 21600000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T02:54:58", + "duration": 21600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-04-27T09:55:56Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T03:30:00", + "duration": 21600000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T03:30:00", + "duration": 21600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-04-27T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T03:30:00", + "duration": 7200000, + "expectedDuration": 21600000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T03:30:00", + "duration": 21600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-04-27T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T05:30:00", + "duration": 21600000, + "percent": 0.75, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T05:30:00", + "duration": 21600000, + "rate": 1.6, + "scheduleName": "basal 3", + "time": "2018-04-27T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T05:30:00", + "duration": 10800000, + "expectedDuration": 21600000, + "percent": 0.75, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T05:30:00", + "duration": 21600000, + "rate": 1.6, + "scheduleName": "basal 3", + "time": "2018-04-27T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T08:30:00", + "duration": 21600000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T08:30:00", + "duration": 21600000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-04-27T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T08:30:00", + "duration": 1498000, + "expectedDuration": 21600000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T08:30:00", + "duration": 21600000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-04-27T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T08:54:58", + "duration": 11102000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T22:00:00", + "duration": 4513000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T23:15:13", + "duration": 147000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T23:17:40", + "duration": 2540000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T00:00:00", + "duration": 635000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T00:10:35", + "duration": 315000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T00:15:50", + "duration": 11650000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T18:00:00", + "duration": 1631000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T18:27:11", + "duration": 3420000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T18:27:11", + "duration": 3420000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-03T01:28:09Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T18:27:11", + "duration": 3419000, + "expectedDuration": 3420000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T18:27:11", + "duration": 3420000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-03T01:28:09Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T19:24:10", + "duration": 9350000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T05:30:00", + "duration": 3903000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T06:35:03", + "duration": 7200000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T06:35:03", + "duration": 7200000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-05-03T13:36:01Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T06:35:03", + "duration": 6897000, + "expectedDuration": 7200000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T06:35:03", + "duration": 7200000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-05-03T13:36:01Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T08:30:00", + "duration": 7200000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T08:30:00", + "duration": 7200000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-03T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T08:30:00", + "duration": 303000, + "expectedDuration": 7200000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T08:30:00", + "duration": 7200000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-03T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T08:35:03", + "duration": 2092000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T09:09:55", + "duration": 43200000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T09:09:55", + "duration": 43200000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-03T16:10:53Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T09:09:55", + "duration": 10205000, + "expectedDuration": 43200000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T09:09:55", + "duration": 43200000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-03T16:10:53Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T12:00:00", + "duration": 16200000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T12:00:00", + "duration": 16200000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-05-03T19:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T12:00:00", + "duration": 5994000, + "expectedDuration": 16200000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T12:00:00", + "duration": 16200000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-05-03T19:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T13:39:54", + "duration": 221000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T13:43:35", + "duration": 10550000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T16:39:25", + "duration": 21498000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T22:37:43", + "duration": 4937000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T00:00:00", + "duration": 5097000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T01:24:57", + "duration": 30600000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T01:24:57", + "duration": 30600000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-05-04T08:25:55Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T01:24:57", + "duration": 7503000, + "expectedDuration": 30600000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T01:24:57", + "duration": 30600000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-05-04T08:25:55Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T03:30:00", + "duration": 30600000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T03:30:00", + "duration": 30600000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-05-04T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T03:30:00", + "duration": 7200000, + "expectedDuration": 30600000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T03:30:00", + "duration": 30600000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-05-04T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T05:30:00", + "duration": 30600000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T05:30:00", + "duration": 30600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-05-04T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T05:30:00", + "duration": 10800000, + "expectedDuration": 30600000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T05:30:00", + "duration": 30600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-05-04T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T08:30:00", + "duration": 30600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T08:30:00", + "duration": 30600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-05-04T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T08:30:00", + "duration": 5097000, + "expectedDuration": 30600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T08:30:00", + "duration": 30600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-05-04T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T09:54:57", + "duration": 4178000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T11:04:35", + "duration": 41400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T11:04:35", + "duration": 41400000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-04T18:05:33Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T11:04:35", + "duration": 3325000, + "expectedDuration": 41400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T11:04:35", + "duration": 41400000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-04T18:05:33Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T12:00:00", + "duration": 41400000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T12:00:00", + "duration": 41400000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-05-04T19:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T12:00:00", + "duration": 21600000, + "expectedDuration": 41400000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T12:00:00", + "duration": 41400000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-05-04T19:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T18:00:00", + "duration": 41400000, + "percent": 0.75, + "rate": 0.86, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T18:00:00", + "duration": 41400000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-05T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T18:00:00", + "duration": 14400000, + "expectedDuration": 41400000, + "percent": 0.75, + "rate": 0.86, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T18:00:00", + "duration": 41400000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-05T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T22:00:00", + "duration": 41400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T22:00:00", + "duration": 41400000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-05T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T22:00:00", + "duration": 2075000, + "expectedDuration": 41400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T22:00:00", + "duration": 41400000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-05T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T22:34:35", + "duration": 5125000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T00:00:00", + "duration": 4232000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T01:10:32", + "duration": 28800000, + "percent": 0.75, + "rate": 1.12, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T01:10:32", + "duration": 28800000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-05-05T08:11:30Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T01:10:32", + "duration": 8368000, + "expectedDuration": 28800000, + "percent": 0.75, + "rate": 1.12, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T01:10:32", + "duration": 28800000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-05-05T08:11:30Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T03:30:00", + "duration": 28800000, + "percent": 0.75, + "rate": 1.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T03:30:00", + "duration": 28800000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-05-05T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T03:30:00", + "duration": 7200000, + "expectedDuration": 28800000, + "percent": 0.75, + "rate": 1.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T03:30:00", + "duration": 28800000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-05-05T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T05:30:00", + "duration": 28800000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T05:30:00", + "duration": 28800000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-05-05T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T05:30:00", + "duration": 10800000, + "expectedDuration": 28800000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T05:30:00", + "duration": 28800000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-05-05T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T08:30:00", + "duration": 28800000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T08:30:00", + "duration": 28800000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-05T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T08:30:00", + "duration": 2432000, + "expectedDuration": 28800000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T08:30:00", + "duration": 28800000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-05T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T09:10:32", + "duration": 10168000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T05:30:00", + "duration": 10250000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:20:50", + "duration": 28800000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:20:50", + "duration": 28800000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-05-06T15:21:48Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:20:50", + "duration": 550000, + "expectedDuration": 28800000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:20:50", + "duration": 28800000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-05-06T15:21:48Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:30:00", + "duration": 28800000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:30:00", + "duration": 28800000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-06T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:30:00", + "duration": 12600000, + "expectedDuration": 28800000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:30:00", + "duration": 28800000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-06T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T12:00:00", + "duration": 28800000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T12:00:00", + "duration": 28800000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-05-06T19:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T12:00:00", + "duration": 15650000, + "expectedDuration": 28800000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T12:00:00", + "duration": 28800000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-05-06T19:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T16:20:50", + "duration": 5950000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T18:00:00", + "duration": 9910000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T20:45:10", + "duration": 257000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T20:49:27", + "duration": 4233000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T03:30:00", + "duration": 4311000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T04:41:51", + "duration": 18428000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T09:48:59", + "duration": 7861000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T18:00:00", + "duration": 11857000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T21:17:37", + "duration": 10800000, + "percent": 1.15, + "rate": 1.32, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T21:17:37", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-11T04:18:35Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T21:17:37", + "duration": 2543000, + "expectedDuration": 10800000, + "percent": 1.15, + "rate": 1.32, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T21:17:37", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-11T04:18:35Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T22:00:00", + "duration": 5460000, + "percent": 1.15, + "rate": 1.66, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T22:00:00", + "duration": 5460000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-11T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T22:00:00", + "duration": 2891000, + "expectedDuration": 5460000, + "percent": 1.15, + "rate": 1.66, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T22:00:00", + "duration": 5460000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-11T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T22:48:11", + "duration": 2421000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T23:28:32", + "duration": 3600000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T23:28:32", + "duration": 3600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-05-11T06:29:30Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T23:28:32", + "duration": 1888000, + "expectedDuration": 3600000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T23:28:32", + "duration": 3600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-05-11T06:29:30Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T00:00:00", + "duration": 3600000, + "percent": 1.25, + "rate": 1.93, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T00:00:00", + "duration": 3600000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-05-11T07:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T00:00:00", + "duration": 1712000, + "expectedDuration": 3600000, + "percent": 1.25, + "rate": 1.93, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T00:00:00", + "duration": 3600000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-05-11T07:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T00:28:32", + "duration": 10888000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T12:00:00", + "duration": 21052000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T17:50:52", + "duration": 10800000, + "percent": 1.25, + "rate": 0.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T17:50:52", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-05-13T00:51:50Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T17:50:52", + "duration": 548000, + "expectedDuration": 10800000, + "percent": 1.25, + "rate": 0.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T17:50:52", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-05-13T00:51:50Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T18:00:00", + "duration": 10800000, + "percent": 1.25, + "rate": 1.43, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T18:00:00", + "duration": 10800000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-05-13T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T18:00:00", + "duration": 10252000, + "expectedDuration": 10800000, + "percent": 1.25, + "rate": 1.43, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T18:00:00", + "duration": 10800000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-05-13T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T20:50:52", + "duration": 4148000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T05:30:00", + "duration": 1821000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T06:00:21", + "duration": 217000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T06:03:58", + "duration": 8762000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T18:00:00", + "duration": 2689000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T18:44:49", + "duration": 3986000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T19:51:15", + "duration": 7725000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T18:00:00", + "duration": 8609000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T20:23:29", + "duration": 9000000, + "percent": 1.5, + "rate": 1.72, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T20:23:29", + "duration": 9000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-16T03:24:27Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T20:23:29", + "duration": 5791000, + "expectedDuration": 9000000, + "percent": 1.5, + "rate": 1.72, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T20:23:29", + "duration": 9000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-16T03:24:27Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T22:00:00", + "duration": 7140000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T22:00:00", + "duration": 7140000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-05-16T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T22:00:00", + "duration": 1292000, + "expectedDuration": 7140000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T22:00:00", + "duration": 7140000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-05-16T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T22:21:32", + "duration": 5908000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T12:00:00", + "duration": 16133000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T16:28:53", + "duration": 113000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T16:30:46", + "duration": 5354000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T12:00:00", + "duration": 19563000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T17:26:03", + "duration": 368000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T17:32:11", + "duration": 1669000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T22:00:00", + "duration": 1859000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T22:30:59", + "duration": 3600000, + "percent": 1.95, + "rate": 2.82, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T22:30:59", + "duration": 3600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-05-23T05:31:57Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T23:30:59", + "duration": 1741000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T08:30:00", + "duration": 8897000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T10:58:17", + "duration": 1755000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T11:27:32", + "duration": 1948000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T12:00:00", + "duration": 19655000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T17:27:35", + "duration": 375000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T17:33:50", + "duration": 1570000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T18:00:00", + "duration": 13374000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T21:42:54", + "duration": 10800000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T21:42:54", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-24T04:43:52Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T21:42:54", + "duration": 1026000, + "expectedDuration": 10800000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T21:42:54", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-24T04:43:52Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T22:00:00", + "duration": 10800000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T22:00:00", + "duration": 10800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-05-24T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T22:00:00", + "duration": 7200000, + "expectedDuration": 10800000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T22:00:00", + "duration": 10800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-05-24T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T00:00:00", + "duration": 10800000, + "percent": 1.4, + "rate": 2.1, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T00:00:00", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-05-24T07:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T00:00:00", + "duration": 2574000, + "expectedDuration": 10800000, + "percent": 1.4, + "rate": 2.1, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T00:00:00", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-05-24T07:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T00:42:54", + "duration": 10026000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T08:30:00", + "duration": 11426000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T11:40:26", + "duration": 7949000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T13:52:55", + "duration": 14825000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T08:30:00", + "duration": 2522000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T09:12:02", + "duration": 14514000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T13:13:56", + "duration": 17164000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T18:00:00", + "duration": 14339000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T21:58:59", + "duration": 1800000, + "percent": 0.09999999999999998, + "rate": 0.11, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T21:58:59", + "duration": 1800000, + "rate": 1.1, + "scheduleName": "basal 3", + "time": "2018-05-30T04:59:57Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T21:58:59", + "duration": 61000, + "expectedDuration": 1800000, + "percent": 0.09999999999999998, + "rate": 0.11, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T21:58:59", + "duration": 1800000, + "rate": 1.1, + "scheduleName": "basal 3", + "time": "2018-05-30T04:59:57Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T22:00:00", + "duration": 1800000, + "percent": 0.09999999999999998, + "rate": 0.14, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T22:00:00", + "duration": 1800000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-05-30T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T22:00:00", + "duration": 1739000, + "expectedDuration": 1800000, + "percent": 0.09999999999999998, + "rate": 0.14, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T22:00:00", + "duration": 1800000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-05-30T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T22:28:59", + "duration": 5461000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T12:00:00", + "duration": 20380000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T17:39:40", + "duration": 3600000, + "percent": 0.65, + "rate": 0.42, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T17:39:40", + "duration": 3600000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-05-31T00:40:38Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T17:39:40", + "duration": 1220000, + "expectedDuration": 3600000, + "percent": 0.65, + "rate": 0.42, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T17:39:40", + "duration": 3600000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-05-31T00:40:38Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T18:00:00", + "duration": 3600000, + "percent": 0.65, + "rate": 0.74, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T18:00:00", + "duration": 3600000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-05-31T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T18:00:00", + "duration": 2380000, + "expectedDuration": 3600000, + "percent": 0.65, + "rate": 0.74, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T18:00:00", + "duration": 3600000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-05-31T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T18:39:40", + "duration": 12020000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T22:00:00", + "duration": 1941000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T22:32:21", + "duration": 332000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T22:37:53", + "duration": 4927000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T00:00:00", + "duration": 7844000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T02:10:44", + "duration": 5400000, + "percent": 0.6, + "rate": 0.9, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T02:10:44", + "duration": 5400000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-06-01T09:11:42Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T02:10:44", + "duration": 4756000, + "expectedDuration": 5400000, + "percent": 0.6, + "rate": 0.9, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T02:10:44", + "duration": 5400000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-06-01T09:11:42Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T03:30:00", + "duration": 5400000, + "percent": 0.6, + "rate": 0.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T03:30:00", + "duration": 5400000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-06-01T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T03:30:00", + "duration": 644000, + "expectedDuration": 5400000, + "percent": 0.6, + "rate": 0.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T03:30:00", + "duration": 5400000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-06-01T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T03:40:44", + "duration": 6556000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T22:00:00", + "duration": 89000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T22:01:29", + "duration": 427000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T22:08:36", + "duration": 6684000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T12:00:00", + "duration": 6521000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:48:41", + "duration": 180000, + "percent": 0.6, + "rate": 0.39, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:48:41", + "duration": 180000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-06-03T20:49:39Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:48:41", + "duration": 154000, + "expectedDuration": 180000, + "percent": 0.6, + "rate": 0.39, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:48:41", + "duration": 180000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-06-03T20:49:39Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:51:15", + "duration": 329000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:56:44", + "duration": 5400000, + "percent": 1.2, + "rate": 0.78, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:56:44", + "duration": 5400000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-06-03T20:57:42Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T15:26:44", + "duration": 9196000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T00:00:00", + "duration": 2718000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T00:45:18", + "duration": 410000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T00:52:08", + "duration": 9472000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T18:00:00", + "duration": 9098000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T20:31:38", + "duration": 238000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T20:35:36", + "duration": 5064000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T12:00:00", + "duration": 6090000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T13:41:30", + "duration": 277000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T13:46:07", + "duration": 8525000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-07T15:08:12", + "duration": 13000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T16:08:25", + "duration": 10295000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-07T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T12:00:00", + "duration": 537000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T12:08:57", + "duration": 190000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T12:12:07", + "duration": 20873000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T12:00:00", + "duration": 3798000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T13:03:18", + "duration": 482000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T14:12:18", + "duration": 13662000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T03:30:00", + "duration": 3971000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T04:36:11", + "duration": 250000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T04:40:21", + "duration": 2979000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T22:00:00", + "duration": 3091000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T22:51:31", + "duration": 1929000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T23:23:40", + "duration": 2180000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T12:00:00", + "duration": 2125000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T12:35:25", + "duration": 1737000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T13:04:22", + "duration": 17738000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T00:00:00", + "duration": 1723000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T00:28:43", + "duration": 27000000, + "percent": 0.65, + "rate": 0.97, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T00:28:43", + "duration": 27000000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-06-15T07:28:43Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T00:28:43", + "duration": 10877000, + "expectedDuration": 27000000, + "percent": 0.65, + "rate": 0.97, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T00:28:43", + "duration": 27000000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-06-15T07:28:43Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T03:30:00", + "duration": 27000000, + "percent": 0.65, + "rate": 0.87, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T03:30:00", + "duration": 27000000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-06-15T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T03:30:00", + "duration": 7200000, + "expectedDuration": 27000000, + "percent": 0.65, + "rate": 0.87, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T03:30:00", + "duration": 27000000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-06-15T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T05:30:00", + "duration": 27000000, + "percent": 0.65, + "rate": 1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T05:30:00", + "duration": 27000000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-06-15T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T05:30:00", + "duration": 8923000, + "expectedDuration": 27000000, + "percent": 0.65, + "rate": 1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T05:30:00", + "duration": 27000000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-06-15T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T07:58:43", + "duration": 1877000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T12:00:00", + "duration": 11186000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T15:06:26", + "duration": 10709000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T18:04:55", + "duration": 14105000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T08:30:00", + "duration": 7555000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T10:35:55", + "duration": 27000000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T10:35:55", + "duration": 27000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-06-18T17:35:55Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T10:35:55", + "duration": 5045000, + "expectedDuration": 27000000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T10:35:55", + "duration": 27000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-06-18T17:35:55Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T12:00:00", + "duration": 27000000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T12:00:00", + "duration": 27000000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-06-18T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T12:00:00", + "duration": 21600000, + "expectedDuration": 27000000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T12:00:00", + "duration": 27000000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-06-18T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T18:00:00", + "duration": 27000000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T18:00:00", + "duration": 27000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-06-19T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T18:00:00", + "duration": 354000, + "expectedDuration": 27000000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T18:00:00", + "duration": 27000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-06-19T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T18:05:54", + "duration": 6111000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T19:47:45", + "duration": 18000000, + "percent": 0.85, + "rate": 0.97, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T19:47:45", + "duration": 18000000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-06-19T02:47:45Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T19:47:45", + "duration": 7935000, + "expectedDuration": 18000000, + "percent": 0.85, + "rate": 0.97, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T19:47:45", + "duration": 18000000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-06-19T02:47:45Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T22:00:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.23, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T22:00:00", + "duration": 18000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-06-19T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T22:00:00", + "duration": 7200000, + "expectedDuration": 18000000, + "percent": 0.85, + "rate": 1.23, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T22:00:00", + "duration": 18000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-06-19T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T00:00:00", + "duration": 17880000, + "percent": 0.85, + "rate": 1.27, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T00:00:00", + "duration": 17880000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-06-19T07:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T00:00:00", + "duration": 2696000, + "expectedDuration": 17880000, + "percent": 0.85, + "rate": 1.27, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T00:00:00", + "duration": 17880000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-06-19T07:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T00:44:56", + "duration": 112000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T00:46:48", + "duration": 9792000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T18:00:00", + "duration": 10769000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T20:59:29", + "duration": 3631000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T08:30:00", + "duration": 10621000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T11:27:01", + "duration": 25200000, + "percent": 0.8, + "rate": 1.12, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T11:27:01", + "duration": 25200000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-06-21T18:27:01Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T11:27:01", + "duration": 1979000, + "expectedDuration": 25200000, + "percent": 0.8, + "rate": 1.12, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T11:27:01", + "duration": 25200000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-06-21T18:27:01Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T12:00:00", + "duration": 14160000, + "percent": 0.8, + "rate": 0.48, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T12:00:00", + "duration": 14160000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-06-21T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T12:00:00", + "duration": 12135000, + "expectedDuration": 14160000, + "percent": 0.8, + "rate": 0.48, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T12:00:00", + "duration": 14160000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-06-21T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T15:22:15", + "duration": 52000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T18:23:07", + "duration": 13013000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T22:00:00", + "duration": 6238000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T23:43:58", + "duration": 870000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T23:58:28", + "duration": 92000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T00:00:00", + "duration": 9249000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T02:34:09", + "duration": 9000000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T02:34:09", + "duration": 9000000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-06-24T06:34:09Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T02:34:09", + "duration": 3351000, + "expectedDuration": 9000000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T02:34:09", + "duration": 9000000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-06-24T06:34:09Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T03:30:00", + "duration": 9000000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T03:30:00", + "duration": 9000000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-06-24T07:30:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T03:30:00", + "duration": 5649000, + "expectedDuration": 9000000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T03:30:00", + "duration": 9000000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-06-24T07:30:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T05:04:09", + "duration": 1551000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T08:30:00", + "duration": 6845000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T10:24:05", + "duration": 10800000, + "percent": 1.35, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T10:24:05", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-06-24T14:24:05Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T10:24:05", + "duration": 5755000, + "expectedDuration": 10800000, + "percent": 1.35, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T10:24:05", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-06-24T14:24:05Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T12:00:00", + "duration": 10800000, + "percent": 1.35, + "rate": 0.81, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T12:00:00", + "duration": 10800000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-06-24T16:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T12:00:00", + "duration": 5045000, + "expectedDuration": 10800000, + "percent": 1.35, + "rate": 0.81, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T12:00:00", + "duration": 10800000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-06-24T16:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T13:24:05", + "duration": 16555000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T05:30:00", + "duration": 8167000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T07:46:07", + "duration": 5319000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T09:14:46", + "duration": 9914000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T22:00:00", + "duration": 2939000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T22:48:59", + "duration": 3600000, + "percent": 0.85, + "rate": 1.19, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T22:48:59", + "duration": 3600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-06-26T02:48:59Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T23:48:59", + "duration": 661000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T00:00:00", + "duration": 10930000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T03:02:10", + "duration": 56000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T00:03:06", + "duration": 12414000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T12:00:00", + "duration": 16156000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T16:29:16", + "duration": 5400000, + "percent": 1.4, + "rate": 0.84, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T16:29:16", + "duration": 5400000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-06-27T23:29:16Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T17:59:16", + "duration": 44000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T12:00:00", + "duration": 7901000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T14:11:41", + "duration": 1866000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T14:42:47", + "duration": 11833000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T08:30:00", + "duration": 7554000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T10:35:54", + "duration": 27000000, + "percent": 0.85, + "rate": 1.19, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T10:35:54", + "duration": 27000000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-06-29T17:35:54Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T10:35:54", + "duration": 5046000, + "expectedDuration": 27000000, + "percent": 0.85, + "rate": 1.19, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T10:35:54", + "duration": 27000000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-06-29T17:35:54Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T12:00:00", + "duration": 27000000, + "percent": 0.85, + "rate": 0.51, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T12:00:00", + "duration": 27000000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-06-29T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T12:00:00", + "duration": 21600000, + "expectedDuration": 27000000, + "percent": 0.85, + "rate": 0.51, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T12:00:00", + "duration": 27000000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-06-29T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T18:00:00", + "duration": 27000000, + "percent": 0.85, + "rate": 0.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T18:00:00", + "duration": 27000000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-06-30T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T18:00:00", + "duration": 354000, + "expectedDuration": 27000000, + "percent": 0.85, + "rate": 0.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T18:00:00", + "duration": 27000000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-06-30T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T18:05:54", + "duration": 14046000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T22:00:00", + "duration": 5283000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T23:28:03", + "duration": 3855000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T00:32:18", + "duration": 10662000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T18:00:00", + "duration": 6951000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T19:55:51", + "duration": 7449000, + "rate": 1, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T22:00:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T05:30:00", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T08:30:00", + "duration": 10564000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T11:26:04", + "duration": 139000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T11:28:23", + "duration": 1897000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T00:00:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T03:30:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T00:00:00", + "duration": 11060000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:04:20", + "duration": 21600000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:04:20", + "duration": 21600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-07-03T10:04:20Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:04:20", + "duration": 1540000, + "expectedDuration": 21600000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:04:20", + "duration": 21600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-07-03T10:04:20Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:30:00", + "duration": 21600000, + "percent": 0.75, + "rate": 0.93, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:30:00", + "duration": 21600000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-07-03T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:30:00", + "duration": 7200000, + "expectedDuration": 21600000, + "percent": 0.75, + "rate": 0.93, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:30:00", + "duration": 21600000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-07-03T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T05:30:00", + "duration": 19560000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T05:30:00", + "duration": 19560000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-07-03T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T05:30:00", + "duration": 10631000, + "expectedDuration": 19560000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T05:30:00", + "duration": 19560000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-07-03T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T08:27:11", + "duration": 10538000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T11:22:49", + "duration": 2231000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T00:00:00", + "duration": 10459000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T02:54:19", + "duration": 7200000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T02:54:19", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-07-04T09:54:19Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T02:54:19", + "duration": 2141000, + "expectedDuration": 7200000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T02:54:19", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-07-04T09:54:19Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T03:30:00", + "duration": 7200000, + "percent": 0.75, + "rate": 0.93, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T03:30:00", + "duration": 7200000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-07-04T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T03:30:00", + "duration": 5059000, + "expectedDuration": 7200000, + "percent": 0.75, + "rate": 0.93, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T03:30:00", + "duration": 7200000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-07-04T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T04:54:19", + "duration": 2141000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T00:00:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T03:30:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T00:00:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T03:30:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T18:00:00", + "duration": 4501000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T19:15:01", + "duration": 442000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T19:22:23", + "duration": 9457000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T00:00:00", + "duration": 9207000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T02:33:27", + "duration": 3600000, + "percent": 1.35, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T02:33:27", + "duration": 3600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-07-07T09:33:27Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T02:33:27", + "duration": 3393000, + "expectedDuration": 3600000, + "percent": 1.35, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T02:33:27", + "duration": 3600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-07-07T09:33:27Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T03:30:00", + "duration": 3600000, + "percent": 1.35, + "rate": 1.68, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T03:30:00", + "duration": 3600000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-07-07T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T03:30:00", + "duration": 207000, + "expectedDuration": 3600000, + "percent": 1.35, + "rate": 1.68, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T03:30:00", + "duration": 3600000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-07-07T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T03:33:27", + "duration": 6993000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T00:00:00", + "duration": 7931000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T02:12:11", + "duration": 1802000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T02:42:13", + "duration": 2867000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T00:00:00", + "duration": 1644000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T00:27:24", + "duration": 387000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T00:33:51", + "duration": 10569000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T05:30:00", + "duration": 11850000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T08:47:30", + "duration": 7734000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T10:56:24", + "duration": 3816000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T12:00:00", + "duration": 11503000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T15:11:43", + "duration": 238000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T15:15:41", + "duration": 9859000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T00:00:00", + "duration": 11695000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:14:55", + "duration": 18000000, + "percent": 0.85, + "rate": 1.1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:14:55", + "duration": 18000000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-07-15T10:14:55Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:14:55", + "duration": 905000, + "expectedDuration": 18000000, + "percent": 0.85, + "rate": 1.1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:14:55", + "duration": 18000000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-07-15T10:14:55Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:30:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.02, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:30:00", + "duration": 18000000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-07-15T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:30:00", + "duration": 7200000, + "expectedDuration": 18000000, + "percent": 0.85, + "rate": 1.02, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:30:00", + "duration": 18000000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-07-15T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T05:30:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T05:30:00", + "duration": 18000000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-07-15T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T05:30:00", + "duration": 9895000, + "expectedDuration": 18000000, + "percent": 0.85, + "rate": 1.1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T05:30:00", + "duration": 18000000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-07-15T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T08:14:55", + "duration": 905000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T08:30:00", + "duration": 4149000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T09:39:09", + "duration": 6405000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T11:25:54", + "duration": 2046000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T12:00:00", + "duration": 10914000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T15:01:54", + "duration": 3600000, + "percent": 1.25, + "rate": 0.56, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T15:01:54", + "duration": 3600000, + "rate": 0.45, + "scheduleName": "basal 3", + "time": "2018-07-17T22:01:54Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T16:01:54", + "duration": 7086000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T12:00:00", + "duration": 14774000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T16:06:14", + "duration": 789000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T16:19:23", + "duration": 6037000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T18:00:00", + "duration": 5447000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T19:30:47", + "duration": 10800000, + "percent": 1.15, + "rate": 1.03, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T19:30:47", + "duration": 10800000, + "rate": 0.9, + "scheduleName": "basal 3", + "time": "2018-07-20T02:30:47Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T19:30:47", + "duration": 8953000, + "expectedDuration": 10800000, + "percent": 1.15, + "rate": 1.03, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T19:30:47", + "duration": 10800000, + "rate": 0.9, + "scheduleName": "basal 3", + "time": "2018-07-20T02:30:47Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T22:00:00", + "duration": 10800000, + "percent": 1.15, + "rate": 1.43, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T22:00:00", + "duration": 10800000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-07-20T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T22:00:00", + "duration": 1847000, + "expectedDuration": 10800000, + "percent": 1.15, + "rate": 1.43, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T22:00:00", + "duration": 10800000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-07-20T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T22:30:47", + "duration": 5353000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T00:00:00", + "duration": 7351000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T02:02:31", + "duration": 5400000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T02:02:31", + "duration": 5400000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-07-22T09:02:31Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T02:02:31", + "duration": 5249000, + "expectedDuration": 5400000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T02:02:31", + "duration": 5400000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-07-22T09:02:31Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T03:30:00", + "duration": 5400000, + "percent": 0.8, + "rate": 0.96, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T03:30:00", + "duration": 5400000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-07-22T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T03:30:00", + "duration": 151000, + "expectedDuration": 5400000, + "percent": 0.8, + "rate": 0.96, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T03:30:00", + "duration": 5400000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-07-22T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T03:32:31", + "duration": 7049000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T00:00:00", + "duration": 829000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T00:13:49", + "duration": 2232000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T00:51:01", + "duration": 9539000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T08:30:00", + "duration": 1596000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T08:56:36", + "duration": 882000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T09:11:18", + "duration": 10122000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T18:00:00", + "duration": 124000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T18:02:04", + "duration": 5400000, + "percent": 0.85, + "rate": 0.76, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T18:02:04", + "duration": 5400000, + "rate": 0.89, + "scheduleName": "basal 3", + "time": "2018-07-27T01:02:04Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T19:32:04", + "duration": 8876000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T00:00:00", + "duration": 860000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T00:14:20", + "duration": 2644000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T00:58:24", + "duration": 9096000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T18:00:00", + "duration": 1335000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T18:22:15", + "duration": 5400000, + "percent": 0.4, + "rate": 0.36, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T18:22:15", + "duration": 5400000, + "rate": 0.9, + "scheduleName": "basal 3", + "time": "2018-07-31T01:22:15Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T19:52:15", + "duration": 7665000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T00:00:00", + "duration": 7906000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T02:11:46", + "duration": 21445000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T08:09:11", + "duration": 1249000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T00:00:00", + "duration": 6044000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T01:40:44", + "duration": 5880000, + "percent": 0.85, + "rate": 1.1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T01:40:44", + "duration": 5880000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-08-03T08:40:44Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T01:40:44", + "duration": 5867000, + "expectedDuration": 5880000, + "percent": 0.85, + "rate": 1.1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T01:40:44", + "duration": 5880000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-08-03T08:40:44Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:18:31", + "duration": 9000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:18:40", + "duration": 7200000, + "percent": 0.7, + "rate": 0.91, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:18:40", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-08-03T10:18:40Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:18:40", + "duration": 680000, + "expectedDuration": 7200000, + "percent": 0.7, + "rate": 0.91, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:18:40", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-08-03T10:18:40Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:30:00", + "duration": 7200000, + "percent": 0.7, + "rate": 0.84, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-08-03T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:30:00", + "duration": 6520000, + "expectedDuration": 7200000, + "percent": 0.7, + "rate": 0.84, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-08-03T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T05:18:40", + "duration": 680000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T12:00:00", + "duration": 8453000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T14:20:53", + "duration": 326000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T14:26:19", + "duration": 12821000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T12:00:00", + "duration": 18803000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T17:13:23", + "duration": 7200000, + "percent": 1.25, + "rate": 0.56, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T17:13:23", + "duration": 7200000, + "rate": 0.45, + "scheduleName": "basal 3", + "time": "2018-08-06T00:13:23Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T17:13:23", + "duration": 2797000, + "expectedDuration": 7200000, + "percent": 1.25, + "rate": 0.56, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T17:13:23", + "duration": 7200000, + "rate": 0.45, + "scheduleName": "basal 3", + "time": "2018-08-06T00:13:23Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T18:00:00", + "duration": 7200000, + "percent": 1.25, + "rate": 1.12, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T18:00:00", + "duration": 7200000, + "rate": 0.9, + "scheduleName": "basal 3", + "time": "2018-08-06T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T18:00:00", + "duration": 4403000, + "expectedDuration": 7200000, + "percent": 1.25, + "rate": 1.12, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T18:00:00", + "duration": 7200000, + "rate": 0.9, + "scheduleName": "basal 3", + "time": "2018-08-06T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T19:13:23", + "duration": 9106000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T21:45:09", + "duration": 251000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T21:49:20", + "duration": 640000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T05:30:00", + "duration": 9183000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T08:03:03", + "duration": 1617000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T03:30:00", + "duration": 5472000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T05:01:12", + "duration": 180000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T05:04:12", + "duration": 1548000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T18:00:00", + "duration": 13178000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T21:39:38", + "duration": 3600000, + "percent": 1.15, + "rate": 1.2, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T21:39:38", + "duration": 3600000, + "rate": 1.04, + "scheduleName": "basal 3", + "time": "2018-08-12T04:39:38Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T21:39:38", + "duration": 1222000, + "expectedDuration": 3600000, + "percent": 1.15, + "rate": 1.2, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T21:39:38", + "duration": 3600000, + "rate": 1.04, + "scheduleName": "basal 3", + "time": "2018-08-12T04:39:38Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T22:00:00", + "duration": 3600000, + "percent": 1.15, + "rate": 1.61, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T22:00:00", + "duration": 3600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-08-12T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T22:00:00", + "duration": 2378000, + "expectedDuration": 3600000, + "percent": 1.15, + "rate": 1.61, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T22:00:00", + "duration": 3600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-08-12T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T22:39:38", + "duration": 4822000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T12:00:00", + "duration": 4236000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T13:10:36", + "duration": 3620000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T14:10:56", + "duration": 3631000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T15:11:27", + "duration": 600000, + "percent": 0.8, + "rate": 0.48, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T15:11:27", + "duration": 600000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-08-12T22:11:27Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T15:11:27", + "duration": 588000, + "expectedDuration": 600000, + "percent": 0.8, + "rate": 0.48, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T15:11:27", + "duration": 600000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-08-12T22:11:27Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T15:21:15", + "duration": 7934000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T17:33:29", + "duration": 1591000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T00:00:00", + "duration": 8499000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T02:21:39", + "duration": 16200000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T02:21:39", + "duration": 16200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-08-14T09:21:39Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T02:21:39", + "duration": 4101000, + "expectedDuration": 16200000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T02:21:39", + "duration": 16200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-08-14T09:21:39Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T03:30:00", + "duration": 16200000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T03:30:00", + "duration": 16200000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-08-14T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T03:30:00", + "duration": 7200000, + "expectedDuration": 16200000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T03:30:00", + "duration": 16200000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-08-14T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T05:30:00", + "duration": 16200000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T05:30:00", + "duration": 16200000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-08-14T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T05:30:00", + "duration": 4899000, + "expectedDuration": 16200000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T05:30:00", + "duration": 16200000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-08-14T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T06:51:39", + "duration": 5901000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T18:00:00", + "duration": 3812000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T19:03:32", + "duration": 6060000, + "percent": 0.75, + "rate": 0.78, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T19:03:32", + "duration": 6060000, + "rate": 1.04, + "scheduleName": "basal 3", + "time": "2018-08-15T02:03:32Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T19:03:32", + "duration": 6031000, + "expectedDuration": 6060000, + "percent": 0.75, + "rate": 0.78, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T19:03:32", + "duration": 6060000, + "rate": 1.04, + "scheduleName": "basal 3", + "time": "2018-08-15T02:03:32Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T20:44:03", + "duration": 9000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T20:44:12", + "duration": 5400000, + "percent": 0.65, + "rate": 0.68, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T20:44:12", + "duration": 5400000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-08-15T03:44:12Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T20:44:12", + "duration": 4548000, + "expectedDuration": 5400000, + "percent": 0.65, + "rate": 0.68, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T20:44:12", + "duration": 5400000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-08-15T03:44:12Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T22:00:00", + "duration": 5400000, + "percent": 0.65, + "rate": 0.91, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T22:00:00", + "duration": 5400000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-08-15T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T22:00:00", + "duration": 852000, + "expectedDuration": 5400000, + "percent": 0.65, + "rate": 0.91, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T22:00:00", + "duration": 5400000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-08-15T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T22:14:12", + "duration": 6348000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T08:30:00", + "duration": 7596000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T10:36:36", + "duration": 5004000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T18:00:00", + "duration": 57000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T18:00:57", + "duration": 10800000, + "percent": 0.19999999999999996, + "rate": 0.18, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T18:00:57", + "duration": 10800000, + "rate": 0.9, + "scheduleName": "basal 3", + "time": "2018-08-16T01:00:57Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T21:00:57", + "duration": 2953000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T21:50:10", + "duration": 240000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T21:54:10", + "duration": 350000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T05:30:00", + "duration": 1539000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T05:55:39", + "duration": 255000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T05:59:54", + "duration": 9006000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T12:00:00", + "duration": 19916000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T17:31:56", + "duration": 9000000, + "percent": 0.6, + "rate": 0.27, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T17:31:56", + "duration": 9000000, + "rate": 0.45, + "scheduleName": "basal 3", + "time": "2018-08-21T00:31:56Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T17:31:56", + "duration": 1684000, + "expectedDuration": 9000000, + "percent": 0.6, + "rate": 0.27, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T17:31:56", + "duration": 9000000, + "rate": 0.45, + "scheduleName": "basal 3", + "time": "2018-08-21T00:31:56Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T18:00:00", + "duration": 9000000, + "percent": 0.6, + "rate": 0.54, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T18:00:00", + "duration": 9000000, + "rate": 0.9, + "scheduleName": "basal 3", + "time": "2018-08-21T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T18:00:00", + "duration": 7316000, + "expectedDuration": 9000000, + "percent": 0.6, + "rate": 0.54, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T18:00:00", + "duration": 9000000, + "rate": 0.9, + "scheduleName": "basal 3", + "time": "2018-08-21T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T20:01:56", + "duration": 7084000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T12:00:00", + "duration": 12721000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T15:32:01", + "duration": 1800000, + "percent": 0.7, + "rate": 0.31, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T15:32:01", + "duration": 1800000, + "rate": 0.44, + "scheduleName": "basal 3", + "time": "2018-08-21T22:32:01Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T16:02:01", + "duration": 7079000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T12:00:00", + "duration": 6854000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T13:54:14", + "duration": 473000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T14:02:07", + "duration": 14273000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T00:00:00", + "duration": 11831000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:17:11", + "duration": 25200000, + "percent": 0.75, + "rate": 0.97, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:17:11", + "duration": 25200000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-08-23T10:17:11Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:17:11", + "duration": 769000, + "expectedDuration": 25200000, + "percent": 0.75, + "rate": 0.97, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:17:11", + "duration": 25200000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-08-23T10:17:11Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:30:00", + "duration": 25200000, + "percent": 0.75, + "rate": 0.9, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:30:00", + "duration": 25200000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-08-23T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:30:00", + "duration": 7200000, + "expectedDuration": 25200000, + "percent": 0.75, + "rate": 0.9, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:30:00", + "duration": 25200000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-08-23T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T05:30:00", + "duration": 25200000, + "percent": 0.75, + "rate": 0.97, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T05:30:00", + "duration": 25200000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-08-23T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T05:30:00", + "duration": 10800000, + "expectedDuration": 25200000, + "percent": 0.75, + "rate": 0.97, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T05:30:00", + "duration": 25200000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-08-23T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T08:30:00", + "duration": 25200000, + "percent": 0.75, + "rate": 0.93, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T08:30:00", + "duration": 25200000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-08-23T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T08:30:00", + "duration": 6431000, + "expectedDuration": 25200000, + "percent": 0.75, + "rate": 0.93, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T08:30:00", + "duration": 25200000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-08-23T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T10:17:11", + "duration": 6169000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T00:00:00", + "duration": 7034000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T01:57:14", + "duration": 25200000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T01:57:14", + "duration": 25200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-08-24T08:57:14Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T01:57:14", + "duration": 5566000, + "expectedDuration": 25200000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T01:57:14", + "duration": 25200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-08-24T08:57:14Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T03:30:00", + "duration": 25200000, + "percent": 0.8, + "rate": 0.96, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T03:30:00", + "duration": 25200000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-08-24T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T03:30:00", + "duration": 7200000, + "expectedDuration": 25200000, + "percent": 0.8, + "rate": 0.96, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T03:30:00", + "duration": 25200000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-08-24T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T05:30:00", + "duration": 25200000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T05:30:00", + "duration": 25200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-08-24T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T05:30:00", + "duration": 10800000, + "expectedDuration": 25200000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T05:30:00", + "duration": 25200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-08-24T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T08:30:00", + "duration": 25200000, + "percent": 0.8, + "rate": 1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T08:30:00", + "duration": 25200000, + "rate": 1.25, + "scheduleName": "basal 3", + "time": "2018-08-24T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T08:30:00", + "duration": 1634000, + "expectedDuration": 25200000, + "percent": 0.8, + "rate": 1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T08:30:00", + "duration": 25200000, + "rate": 1.25, + "scheduleName": "basal 3", + "time": "2018-08-24T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T08:57:14", + "duration": 10966000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T12:00:00", + "duration": 8532000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T14:22:12", + "duration": 7200000, + "percent": 0.30000000000000004, + "rate": 0.13, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T14:22:12", + "duration": 7200000, + "rate": 0.43, + "scheduleName": "basal 3", + "time": "2018-08-24T21:22:12Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T16:22:12", + "duration": 5868000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T18:00:00", + "duration": 14095000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T21:54:55", + "duration": 280000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T21:59:35", + "duration": 25000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T03:30:00", + "duration": 6075000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T05:11:15", + "duration": 397000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T05:17:52", + "duration": 728000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T12:00:00", + "duration": 4392000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T13:13:12", + "duration": 17592000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T18:06:24", + "duration": 14016000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T08:30:00", + "duration": 9169000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T11:02:49", + "duration": 3431000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T05:30:00", + "duration": 4177000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T06:39:37", + "duration": 10025000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T09:26:42", + "duration": 9198000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T12:00:00", + "duration": 19217000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T17:20:17", + "duration": 6688000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T19:11:45", + "duration": 10095000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T00:00:00", + "duration": 1827000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T00:30:27", + "duration": 1374000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T00:53:21", + "duration": 9399000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T08:30:00", + "duration": 2264000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T09:07:44", + "duration": 7415000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T11:11:19", + "duration": 1593000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T11:37:52", + "duration": 5400000, + "percent": 1.35, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T11:37:52", + "duration": 5400000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-09-14T18:37:52Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T11:37:52", + "duration": 1328000, + "expectedDuration": 5400000, + "percent": 1.35, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T11:37:52", + "duration": 5400000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-09-14T18:37:52Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T12:00:00", + "duration": 5400000, + "percent": 1.35, + "rate": 0.81, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T12:00:00", + "duration": 5400000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-14T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T12:00:00", + "duration": 4072000, + "expectedDuration": 5400000, + "percent": 1.35, + "rate": 0.81, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T12:00:00", + "duration": 5400000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-14T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T13:07:52", + "duration": 17528000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T12:00:00", + "duration": 142000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T12:02:22", + "duration": 3600000, + "percent": 0.7, + "rate": 0.42, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T12:02:22", + "duration": 3600000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-15T19:02:22Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T13:02:22", + "duration": 17858000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T08:30:00", + "duration": 5863000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T10:07:43", + "duration": 5400000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T10:07:43", + "duration": 5400000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-09-16T17:07:43Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T11:37:43", + "duration": 1337000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T18:00:00", + "duration": 4181000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T19:09:41", + "duration": 3495000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T20:07:56", + "duration": 6724000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T12:00:00", + "duration": 5103000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T13:25:03", + "duration": 76000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T13:26:19", + "duration": 16421000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T18:00:00", + "duration": 13638000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T21:47:18", + "duration": 533000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T21:56:11", + "duration": 229000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T18:00:00", + "duration": 2999000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T18:49:59", + "duration": 3600000, + "percent": 1.45, + "rate": 1.52, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T18:49:59", + "duration": 3600000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-09-21T01:49:59Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T19:49:59", + "duration": 7801000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T00:00:00", + "duration": 2319000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T00:38:39", + "duration": 7200000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T00:38:39", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-09-21T07:38:39Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T02:38:39", + "duration": 3081000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T00:00:00", + "duration": 1518000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T00:25:18", + "duration": 3600000, + "percent": 0.7, + "rate": 1.05, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T00:25:18", + "duration": 3600000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-09-22T07:25:18Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T01:25:18", + "duration": 7482000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T05:30:00", + "duration": 1230000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T05:50:30", + "duration": 18830000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T11:04:20", + "duration": 3340000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T12:00:00", + "duration": 19246000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T17:20:46", + "duration": 7200000, + "percent": 1.7, + "rate": 1.02, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T17:20:46", + "duration": 7200000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-24T00:20:46Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T17:20:46", + "duration": 2354000, + "expectedDuration": 7200000, + "percent": 1.7, + "rate": 1.02, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T17:20:46", + "duration": 7200000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-24T00:20:46Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T18:00:00", + "duration": 7200000, + "percent": 1.7, + "rate": 1.78, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T18:00:00", + "duration": 7200000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-09-24T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T18:00:00", + "duration": 4846000, + "expectedDuration": 7200000, + "percent": 1.7, + "rate": 1.78, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T18:00:00", + "duration": 7200000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-09-24T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T19:20:46", + "duration": 9554000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T08:30:00", + "duration": 2085000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T09:04:45", + "duration": 4217000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T10:15:02", + "duration": 6298000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T12:00:00", + "duration": 17944000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T16:59:04", + "duration": 3600000, + "percent": 1.65, + "rate": 0.99, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T16:59:04", + "duration": 3600000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-26T23:59:04Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T17:59:04", + "duration": 56000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T18:00:00", + "duration": 5666000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T19:34:26", + "duration": 5400000, + "percent": 1.9, + "rate": 1.99, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T19:34:26", + "duration": 5400000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-09-27T02:34:26Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T21:04:26", + "duration": 3334000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T00:00:00", + "duration": 2082000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T00:34:42", + "duration": 3600000, + "percent": 1.35, + "rate": 2.02, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T00:34:42", + "duration": 3600000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-09-27T07:34:42Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T01:34:42", + "duration": 6918000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T12:00:00", + "duration": 5752000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T13:35:52", + "duration": 204000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T13:39:16", + "duration": 5345000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T15:08:21", + "duration": 5400000, + "percent": 1.55, + "rate": 0.93, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T15:08:21", + "duration": 5400000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-27T22:08:21Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T16:38:21", + "duration": 4899000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T18:00:00", + "duration": 6720000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T19:52:00", + "duration": 645000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T20:02:45", + "duration": 7035000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T05:30:00", + "duration": 9805000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:13:25", + "duration": 5400000, + "percent": 1.5, + "rate": 2.32, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:13:25", + "duration": 5400000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-09-28T15:13:25Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:13:25", + "duration": 995000, + "expectedDuration": 5400000, + "percent": 1.5, + "rate": 2.32, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:13:25", + "duration": 5400000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-09-28T15:13:25Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:30:00", + "duration": 5400000, + "percent": 1.5, + "rate": 2.1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:30:00", + "duration": 5400000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-09-28T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:30:00", + "duration": 4405000, + "expectedDuration": 5400000, + "percent": 1.5, + "rate": 2.1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:30:00", + "duration": 5400000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-09-28T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T09:43:25", + "duration": 8195000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T12:00:00", + "duration": 2532000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T12:42:12", + "duration": 4620000, + "percent": 1.4, + "rate": 0.84, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T12:42:12", + "duration": 4620000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-28T19:42:12Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T12:42:12", + "duration": 4596000, + "expectedDuration": 4620000, + "percent": 1.4, + "rate": 0.84, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T12:42:12", + "duration": 4620000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-28T19:42:12Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T13:58:48", + "duration": 14000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T13:59:02", + "duration": 5400000, + "percent": 1.55, + "rate": 0.93, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T13:59:02", + "duration": 5400000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-28T20:59:02Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T15:29:02", + "duration": 6819000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T17:22:41", + "duration": 7200000, + "percent": 1.35, + "rate": 0.81, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T17:22:41", + "duration": 7200000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-29T00:22:41Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T17:22:41", + "duration": 2239000, + "expectedDuration": 7200000, + "percent": 1.35, + "rate": 0.81, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T17:22:41", + "duration": 7200000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-29T00:22:41Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T18:00:00", + "duration": 7200000, + "percent": 1.35, + "rate": 1.41, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T18:00:00", + "duration": 7200000, + "rate": 1.04, + "scheduleName": "basal 3", + "time": "2018-09-29T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T18:00:00", + "duration": 4961000, + "expectedDuration": 7200000, + "percent": 1.35, + "rate": 1.41, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T18:00:00", + "duration": 7200000, + "rate": 1.04, + "scheduleName": "basal 3", + "time": "2018-09-29T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T19:22:41", + "duration": 9439000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T00:00:00", + "duration": 9113000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T02:31:53", + "duration": 5400000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T02:31:53", + "duration": 5400000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-09-29T09:31:53Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T02:31:53", + "duration": 3487000, + "expectedDuration": 5400000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T02:31:53", + "duration": 5400000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-09-29T09:31:53Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T03:30:00", + "duration": 5400000, + "percent": 1.25, + "rate": 1.68, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T03:30:00", + "duration": 5400000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-09-29T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T03:30:00", + "duration": 1913000, + "expectedDuration": 5400000, + "percent": 1.25, + "rate": 1.68, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T03:30:00", + "duration": 5400000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-09-29T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T04:01:53", + "duration": 5287000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T08:30:00", + "duration": 4914000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T09:51:54", + "duration": 9000000, + "percent": 0.8, + "rate": 1.12, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T09:51:54", + "duration": 9000000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-09-29T16:51:54Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T09:51:54", + "duration": 7686000, + "expectedDuration": 9000000, + "percent": 0.8, + "rate": 1.12, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T09:51:54", + "duration": 9000000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-09-29T16:51:54Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T12:00:00", + "duration": 9000000, + "percent": 0.8, + "rate": 0.48, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T12:00:00", + "duration": 9000000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-29T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T12:00:00", + "duration": 1314000, + "expectedDuration": 9000000, + "percent": 0.8, + "rate": 0.48, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T12:00:00", + "duration": 9000000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-29T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T12:21:54", + "duration": 20286000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T18:00:00", + "duration": 1416000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T18:23:36", + "duration": 10800000, + "percent": 1.5, + "rate": 1.57, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T18:23:36", + "duration": 10800000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-09-30T01:23:36Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T21:23:36", + "duration": 2184000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T08:30:00", + "duration": 3040000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T09:20:40", + "duration": 3159000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T10:13:19", + "duration": 6401000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T12:00:00", + "duration": 4788000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T13:19:48", + "duration": 7200000, + "percent": 1.45, + "rate": 0.87, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T13:19:48", + "duration": 7200000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-30T20:19:48Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T15:19:48", + "duration": 4339000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T16:32:07", + "duration": 7200000, + "percent": 1.5, + "rate": 0.9, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T16:32:07", + "duration": 7200000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-30T23:32:07Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T16:32:07", + "duration": 5273000, + "expectedDuration": 7200000, + "percent": 1.5, + "rate": 0.9, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T16:32:07", + "duration": 7200000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-30T23:32:07Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T18:00:00", + "duration": 7200000, + "percent": 1.5, + "rate": 1.57, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T18:00:00", + "duration": 7200000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-10-01T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T18:00:00", + "duration": 1927000, + "expectedDuration": 7200000, + "percent": 1.5, + "rate": 1.57, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T18:00:00", + "duration": 7200000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-10-01T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T18:32:07", + "duration": 12473000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T18:00:00", + "duration": 4755000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T19:19:15", + "duration": 9000000, + "percent": 1.5, + "rate": 1.57, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T19:19:15", + "duration": 9000000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-10-02T02:19:15Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T21:49:15", + "duration": 645000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T18:00:00", + "duration": 12431000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T21:27:11", + "duration": 10800000, + "percent": 1.95, + "rate": 2.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T21:27:11", + "duration": 10800000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-10-03T04:27:11Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T21:27:11", + "duration": 1969000, + "expectedDuration": 10800000, + "percent": 1.95, + "rate": 2.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T21:27:11", + "duration": 10800000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-10-03T04:27:11Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T22:00:00", + "duration": 10800000, + "percent": 1.95, + "rate": 2.73, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T22:00:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-03T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T22:00:00", + "duration": 7200000, + "expectedDuration": 10800000, + "percent": 1.95, + "rate": 2.73, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T22:00:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-03T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T00:00:00", + "duration": 10800000, + "percent": 1.95, + "rate": 2.92, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T00:00:00", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-10-03T07:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T00:00:00", + "duration": 1631000, + "expectedDuration": 10800000, + "percent": 1.95, + "rate": 2.92, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T00:00:00", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-10-03T07:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T00:27:11", + "duration": 10969000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T18:00:00", + "duration": 260000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T18:04:20", + "duration": 3314000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T18:59:34", + "duration": 7000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T18:59:41", + "duration": 45000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T19:00:26", + "duration": 10774000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T05:30:00", + "duration": 7859000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T07:40:59", + "duration": 36000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T07:41:35", + "duration": 2905000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T08:30:00", + "duration": 5764000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T10:06:04", + "duration": 7200000, + "percent": 1.25, + "rate": 1.75, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T10:06:04", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-04T17:06:04Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T10:06:04", + "duration": 6836000, + "expectedDuration": 7200000, + "percent": 1.25, + "rate": 1.75, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T10:06:04", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-04T17:06:04Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T12:00:00", + "duration": 7200000, + "percent": 1.25, + "rate": 0.75, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T12:00:00", + "duration": 7200000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-10-04T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T12:00:00", + "duration": 364000, + "expectedDuration": 7200000, + "percent": 1.25, + "rate": 0.75, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T12:00:00", + "duration": 7200000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-10-04T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T12:06:04", + "duration": 21236000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T08:30:00", + "duration": 11084000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T11:34:44", + "duration": 3600000, + "percent": 0.7, + "rate": 0.98, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T11:34:44", + "duration": 3600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-05T18:34:44Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T11:34:44", + "duration": 1516000, + "expectedDuration": 3600000, + "percent": 0.7, + "rate": 0.98, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T11:34:44", + "duration": 3600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-05T18:34:44Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T12:00:00", + "duration": 3600000, + "percent": 0.7, + "rate": 0.42, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T12:00:00", + "duration": 3600000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-10-05T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T12:00:00", + "duration": 2084000, + "expectedDuration": 3600000, + "percent": 0.7, + "rate": 0.42, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T12:00:00", + "duration": 3600000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-10-05T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T12:34:44", + "duration": 19516000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T12:00:00", + "duration": 12872000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T15:34:32", + "duration": 4983000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T16:57:35", + "duration": 3745000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T18:00:00", + "duration": 5583000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T19:33:03", + "duration": 7200000, + "percent": 1.55, + "rate": 1.62, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T19:33:03", + "duration": 7200000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-10-07T02:33:03Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T21:33:03", + "duration": 1617000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T00:00:00", + "duration": 2776000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T00:46:16", + "duration": 7200000, + "percent": 1.3, + "rate": 2.01, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T00:46:16", + "duration": 7200000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-10-07T07:46:16Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T02:46:16", + "duration": 2624000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T22:00:00", + "duration": 1978000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T22:32:58", + "duration": 14400000, + "percent": 1.75, + "rate": 2.45, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T22:32:58", + "duration": 14400000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-08T05:32:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T22:32:58", + "duration": 5222000, + "expectedDuration": 14400000, + "percent": 1.75, + "rate": 2.45, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T22:32:58", + "duration": 14400000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-08T05:32:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T00:00:00", + "duration": 14400000, + "percent": 1.75, + "rate": 2.71, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T00:00:00", + "duration": 14400000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-10-08T07:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T00:00:00", + "duration": 9178000, + "expectedDuration": 14400000, + "percent": 1.75, + "rate": 2.71, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T00:00:00", + "duration": 14400000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-10-08T07:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T02:32:58", + "duration": 3422000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T05:30:00", + "duration": 8216000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T07:46:56", + "duration": 670000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T07:58:06", + "duration": 9000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T07:58:15", + "duration": 3600000, + "percent": 1.45, + "rate": 2.24, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T07:58:15", + "duration": 3600000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-10-09T14:58:15Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T07:58:15", + "duration": 1905000, + "expectedDuration": 3600000, + "percent": 1.45, + "rate": 2.24, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T07:58:15", + "duration": 3600000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-10-09T14:58:15Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T08:30:00", + "duration": 3600000, + "percent": 1.45, + "rate": 2.03, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T08:30:00", + "duration": 3600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-09T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T08:30:00", + "duration": 1695000, + "expectedDuration": 3600000, + "percent": 1.45, + "rate": 2.03, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T08:30:00", + "duration": 3600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-09T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T08:58:15", + "duration": 10905000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T18:00:00", + "duration": 1977000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T18:32:57", + "duration": 4784000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T19:52:41", + "duration": 7639000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T08:30:00", + "duration": 993000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T08:46:33", + "duration": 11607000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T03:30:00", + "duration": 14251000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T07:27:31", + "duration": 3604000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T08:27:35", + "duration": 145000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T12:00:00", + "duration": 1528000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T12:25:28", + "duration": 5400000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T12:25:28", + "duration": 5400000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-10-12T19:25:28Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T12:25:28", + "duration": 5399000, + "expectedDuration": 5400000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T12:25:28", + "duration": 5400000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-10-12T19:25:28Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T13:55:27", + "duration": 14673000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:00:00", + "duration": 887000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:14:47", + "duration": 60000, + "percent": 0.6, + "rate": 0.99, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:14:47", + "duration": 60000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-13T07:14:47Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:14:47", + "duration": 17000, + "expectedDuration": 60000, + "percent": 0.6, + "rate": 0.99, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:14:47", + "duration": 60000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-13T07:14:47Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:15:04", + "duration": 23000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:15:27", + "duration": 3147000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T01:07:54", + "duration": 435000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T04:15:09", + "duration": 14000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T04:15:23", + "duration": 9240000, + "percent": 0.65, + "rate": 1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T04:15:23", + "duration": 9240000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-10-13T08:15:23Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T04:15:23", + "duration": 9089000, + "expectedDuration": 9240000, + "percent": 0.65, + "rate": 1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T04:15:23", + "duration": 9240000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-10-13T08:15:23Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T06:46:52", + "duration": 297000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T06:51:49", + "duration": 17000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T06:52:06", + "duration": 3600000, + "percent": 0.85, + "rate": 1.31, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T06:52:06", + "duration": 3600000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-10-13T10:52:06Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T07:52:06", + "duration": 2274000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T18:00:00", + "duration": 10401000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T20:53:21", + "duration": 16200000, + "percent": 1.65, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T20:53:21", + "duration": 16200000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-14T00:53:21Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T20:53:21", + "duration": 3999000, + "expectedDuration": 16200000, + "percent": 1.65, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T20:53:21", + "duration": 16200000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-14T00:53:21Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T22:00:00", + "duration": 16200000, + "percent": 1.65, + "rate": 2.39, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T22:00:00", + "duration": 16200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-14T02:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T22:00:00", + "duration": 7200000, + "expectedDuration": 16200000, + "percent": 1.65, + "rate": 2.39, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T22:00:00", + "duration": 16200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-14T02:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T00:00:00", + "duration": 16200000, + "percent": 1.65, + "rate": 2.72, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T00:00:00", + "duration": 16200000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-14T04:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T00:00:00", + "duration": 5001000, + "expectedDuration": 16200000, + "percent": 1.65, + "rate": 2.72, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T00:00:00", + "duration": 16200000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-14T04:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T01:23:21", + "duration": 566000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T01:32:47", + "duration": 12600000, + "percent": 1.65, + "rate": 2.72, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T01:32:47", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-14T05:32:47Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T01:32:47", + "duration": 7033000, + "expectedDuration": 12600000, + "percent": 1.65, + "rate": 2.72, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T01:32:47", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-14T05:32:47Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T03:30:00", + "duration": 12600000, + "percent": 1.65, + "rate": 2.55, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T03:30:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-10-14T07:30:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T03:30:00", + "duration": 5567000, + "expectedDuration": 12600000, + "percent": 1.65, + "rate": 2.55, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T03:30:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-10-14T07:30:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T05:02:47", + "duration": 12433000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T12:00:00", + "duration": 18910000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T17:15:10", + "duration": 10800000, + "percent": 1.45, + "rate": 0.94, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T17:15:10", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-14T21:15:10Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T17:15:10", + "duration": 2690000, + "expectedDuration": 10800000, + "percent": 1.45, + "rate": 0.94, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T17:15:10", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-14T21:15:10Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T18:00:00", + "duration": 10800000, + "percent": 1.45, + "rate": 1.66, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T18:00:00", + "duration": 10800000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-10-14T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T18:00:00", + "duration": 8110000, + "expectedDuration": 10800000, + "percent": 1.45, + "rate": 1.66, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T18:00:00", + "duration": 10800000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-10-14T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T20:15:10", + "duration": 6290000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T12:00:00", + "duration": 8739000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T14:25:39", + "duration": 1563000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T14:51:42", + "duration": 5877000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T16:29:39", + "duration": 10800000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T16:29:39", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-15T20:29:39Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T16:29:39", + "duration": 5421000, + "expectedDuration": 10800000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T16:29:39", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-15T20:29:39Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T18:00:00", + "duration": 10800000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T18:00:00", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-15T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T18:00:00", + "duration": 5379000, + "expectedDuration": 10800000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T18:00:00", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-15T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T19:29:39", + "duration": 9021000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T18:00:00", + "duration": 813000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T18:13:33", + "duration": 18000000, + "percent": 1.65, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T18:13:33", + "duration": 18000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-16T22:13:33Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T18:13:33", + "duration": 13587000, + "expectedDuration": 18000000, + "percent": 1.65, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T18:13:33", + "duration": 18000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-16T22:13:33Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T22:00:00", + "duration": 18000000, + "percent": 1.65, + "rate": 2.39, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T22:00:00", + "duration": 18000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-17T02:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T22:00:00", + "duration": 4413000, + "expectedDuration": 18000000, + "percent": 1.65, + "rate": 2.39, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T22:00:00", + "duration": 18000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-17T02:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T23:13:33", + "duration": 2787000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T12:00:00", + "duration": 12800000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T15:33:20", + "duration": 256000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T15:37:36", + "duration": 8544000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T00:00:00", + "duration": 586000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T00:09:46", + "duration": 12600000, + "percent": 1.7, + "rate": 2.8, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T00:09:46", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-19T04:09:46Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T00:09:46", + "duration": 12014000, + "expectedDuration": 12600000, + "percent": 1.7, + "rate": 2.8, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T00:09:46", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-19T04:09:46Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T03:30:00", + "duration": 12600000, + "percent": 1.7, + "rate": 2.63, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T03:30:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-10-19T07:30:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T03:30:00", + "duration": 586000, + "expectedDuration": 12600000, + "percent": 1.7, + "rate": 2.63, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T03:30:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-10-19T07:30:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T03:39:46", + "duration": 17414000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T12:00:00", + "duration": 17302000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T16:48:22", + "duration": 7200000, + "percent": 1.6, + "rate": 1.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T16:48:22", + "duration": 7200000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-19T20:48:22Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T16:48:22", + "duration": 4298000, + "expectedDuration": 7200000, + "percent": 1.6, + "rate": 1.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T16:48:22", + "duration": 7200000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-19T20:48:22Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T18:00:00", + "duration": 7200000, + "percent": 1.6, + "rate": 1.84, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T18:00:00", + "duration": 7200000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-19T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T18:00:00", + "duration": 2902000, + "expectedDuration": 7200000, + "percent": 1.6, + "rate": 1.84, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T18:00:00", + "duration": 7200000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-19T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T18:48:22", + "duration": 11498000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T12:00:00", + "duration": 19646000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T17:27:26", + "duration": 10800000, + "percent": 1.75, + "rate": 1.13, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T17:27:26", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-20T21:27:26Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T17:27:26", + "duration": 1954000, + "expectedDuration": 10800000, + "percent": 1.75, + "rate": 1.13, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T17:27:26", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-20T21:27:26Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T18:00:00", + "duration": 10800000, + "percent": 1.75, + "rate": 2.01, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T18:00:00", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-20T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T18:00:00", + "duration": 8846000, + "expectedDuration": 10800000, + "percent": 1.75, + "rate": 2.01, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T18:00:00", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-20T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T20:27:26", + "duration": 5554000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T22:00:00", + "duration": 3002000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T22:50:02", + "duration": 416000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T22:56:58", + "duration": 3782000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T12:00:00", + "duration": 11357000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T15:09:17", + "duration": 12600000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T15:09:17", + "duration": 12600000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-22T19:09:17Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T15:09:17", + "duration": 10243000, + "expectedDuration": 12600000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T15:09:17", + "duration": 12600000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-22T19:09:17Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T18:00:00", + "duration": 12600000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T18:00:00", + "duration": 12600000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-22T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T18:00:00", + "duration": 2357000, + "expectedDuration": 12600000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T18:00:00", + "duration": 12600000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-22T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T18:39:17", + "duration": 12043000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T08:30:00", + "duration": 9912000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T11:15:12", + "duration": 9000000, + "percent": 0.4, + "rate": 0.58, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T11:15:12", + "duration": 9000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-23T15:15:12Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T11:15:12", + "duration": 2688000, + "expectedDuration": 9000000, + "percent": 0.4, + "rate": 0.58, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T11:15:12", + "duration": 9000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-23T15:15:12Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T12:00:00", + "duration": 8340000, + "percent": 0.4, + "rate": 0.26, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T12:00:00", + "duration": 8340000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-23T16:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T12:00:00", + "duration": 5612000, + "expectedDuration": 8340000, + "percent": 0.4, + "rate": 0.26, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T12:00:00", + "duration": 8340000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-23T16:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T13:33:32", + "duration": 38000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T10:34:10", + "duration": 627000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T10:44:37", + "duration": 3600000, + "percent": 1.15, + "rate": 1.66, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T10:44:37", + "duration": 3600000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-10-23T17:44:37Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T11:44:37", + "duration": 923000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T18:00:00", + "duration": 10191000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T20:49:51", + "duration": 12600000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T20:49:51", + "duration": 12600000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-24T03:49:51Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T20:49:51", + "duration": 4209000, + "expectedDuration": 12600000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T20:49:51", + "duration": 12600000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-24T03:49:51Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T22:00:00", + "duration": 12600000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T22:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-24T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T22:00:00", + "duration": 7200000, + "expectedDuration": 12600000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T22:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-24T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T00:00:00", + "duration": 12600000, + "percent": 1.4, + "rate": 2.31, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-24T07:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T00:00:00", + "duration": 1191000, + "expectedDuration": 12600000, + "percent": 1.4, + "rate": 2.31, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-24T07:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T00:19:51", + "duration": 11409000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T03:30:00", + "duration": 2088000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T04:04:48", + "duration": 20248000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T09:42:16", + "duration": 8264000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T12:00:00", + "duration": 7234000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T14:00:34", + "duration": 5400000, + "percent": 1.6, + "rate": 1.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T14:00:34", + "duration": 5400000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-25T21:00:34Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T15:30:34", + "duration": 8966000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T03:30:00", + "duration": 16729000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:08:49", + "duration": 7200000, + "percent": 1.5, + "rate": 2.32, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:08:49", + "duration": 7200000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-10-27T15:08:49Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:08:49", + "duration": 1271000, + "expectedDuration": 7200000, + "percent": 1.5, + "rate": 2.32, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:08:49", + "duration": 7200000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-10-27T15:08:49Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:30:00", + "duration": 7200000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-27T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:30:00", + "duration": 5929000, + "expectedDuration": 7200000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-27T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T10:08:49", + "duration": 6671000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T12:00:00", + "duration": 65000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T12:01:05", + "duration": 421000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T12:08:06", + "duration": 21114000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T18:00:00", + "duration": 4889000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T19:21:29", + "duration": 14570000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T23:24:19", + "duration": 2141000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T03:30:00", + "duration": 13402000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T07:13:22", + "duration": 17773000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T12:09:35", + "duration": 5452000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T13:40:27", + "duration": 9000000, + "percent": 1.5, + "rate": 0.97, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T13:40:27", + "duration": 9000000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-11-03T20:40:27Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T16:10:27", + "duration": 6573000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T03:30:00", + "duration": 6646000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T05:20:46", + "duration": 81000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T04:22:07", + "duration": 14873000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T18:00:00", + "duration": 3581000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "annotations": [{ "code": "basal/unknown-duration" }], + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T18:59:41", + "duration": 0 + } +] +` + +func GetJFBasalData() []map[string]interface{} { + data := []map[string]interface{}{} + json.Unmarshal([]byte(jfBasalStr), &data) + return data +} + +var platformBasalStr = `[ + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T22:00:00", + "duration": 1217000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T22:20:17", + "duration": 800000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T22:33:37", + "duration": 5183000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T00:00:00", + "duration": 7992000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T02:13:12", + "duration": 2334000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T05:52:06", + "duration": 6987000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T07:48:33", + "duration": 1140000, + "percent": 0.4, + "rate": 0.62, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T08:07:02", + "duration": 2631000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T08:50:53", + "duration": 8779000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:17:12", + "duration": 1800000, + "percent": 0.6, + "rate": 0.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:47:12", + "duration": 592000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:57:04", + "duration": 7200000, + "percent": 0.35, + "rate": 0.5, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.43, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T12:00:00", + "duration": 7200000, + "percent": 0.35, + "rate": 0.22, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.63, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T13:57:04", + "duration": 14576000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T08:30:00", + "duration": 3356000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T09:25:56", + "duration": 7200000, + "percent": 0.5, + "rate": 0.72, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T11:25:56", + "duration": 2044000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T12:00:00", + "duration": 1425000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T12:23:45", + "duration": 5400000, + "percent": 0.5, + "rate": 0.32, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T13:53:45", + "duration": 14775000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T00:00:00", + "duration": 2543000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T00:42:23", + "duration": 12600000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T03:30:00", + "duration": 12600000, + "percent": 0.65, + "rate": 0.84, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.29, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T04:12:23", + "duration": 4657000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T08:30:00", + "duration": 10937000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T11:32:17", + "duration": 10800000, + "percent": 0.6, + "rate": 0.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T12:00:00", + "duration": 7860000, + "percent": 0.6, + "rate": 0.39, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T13:42:37", + "duration": 47000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T13:43:24", + "duration": 10800000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T16:43:24", + "duration": 4596000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T18:00:00", + "duration": 2896000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T18:48:16", + "duration": 4862000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T20:09:18", + "duration": 6642000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T00:00:00", + "duration": 10582000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T02:56:22", + "duration": 21600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T03:30:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T05:30:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T08:30:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T08:56:22", + "duration": 11018000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T12:00:00", + "duration": 7848000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T14:10:48", + "duration": 9000000, + "percent": 1.25, + "rate": 0.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T16:40:48", + "duration": 4752000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T18:00:00", + "duration": 4786000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T19:19:46", + "duration": 492000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T19:27:58", + "duration": 9122000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T08:30:00", + "duration": 5770000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:06:10", + "duration": 1860000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:36:13", + "duration": 13000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:36:26", + "duration": 3600000, + "percent": 1.15, + "rate": 1.66, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T11:36:26", + "duration": 1414000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T12:00:00", + "duration": 19357000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T17:22:37", + "duration": 385000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T17:29:02", + "duration": 1858000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T12:00:00", + "duration": 499000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T12:08:19", + "duration": 9000000, + "percent": 0.55, + "rate": 0.35, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T14:38:19", + "duration": 8117000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T16:53:36", + "duration": 5400000, + "percent": 1.5, + "rate": 0.97, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T18:00:00", + "duration": 5400000, + "percent": 1.5, + "rate": 1.72, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T18:23:36", + "duration": 12984000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T22:00:00", + "duration": 1335000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T22:22:15", + "duration": 7200000, + "percent": 0.7, + "rate": 0.91, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T00:00:00", + "duration": 7200000, + "percent": 0.7, + "rate": 1.01, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T00:22:15", + "duration": 5651000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T01:56:26", + "duration": 16200000, + "percent": 0.5, + "rate": 0.72, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:30:00", + "duration": 6360000, + "percent": 0.5, + "rate": 0.65, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:41:53", + "duration": 14000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:42:07", + "duration": 480000, + "percent": 0.15000000000000002, + "rate": 0.19, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.27, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:49:40", + "duration": 21000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:50:01", + "duration": 1260000, + "rate": 0 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T04:10:44", + "duration": 17000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T04:11:01", + "duration": 25200000, + "percent": 0.30000000000000004, + "rate": 0.39, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T05:30:00", + "duration": 25200000, + "percent": 0.30000000000000004, + "rate": 0.46, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.53, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T08:30:00", + "duration": 21000000, + "percent": 0.30000000000000004, + "rate": 0.43, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.43, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T10:00:43", + "duration": 7157000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T08:30:00", + "duration": 7831000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T10:40:31", + "duration": 3660000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T11:41:01", + "duration": 26048000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T18:55:09", + "duration": 11091000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T08:30:00", + "duration": 4143000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T09:39:03", + "duration": 5400000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T11:09:03", + "duration": 3057000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T12:00:00", + "duration": 11173000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T15:06:13", + "duration": 10800000, + "percent": 0.5, + "rate": 0.32, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T18:00:00", + "duration": 10800000, + "percent": 0.5, + "rate": 0.57, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.14, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T18:06:13", + "duration": 14027000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T05:30:00", + "duration": 7330000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T07:32:10", + "duration": 8320000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T09:50:50", + "duration": 7750000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T12:00:00", + "duration": 13768000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T15:49:28", + "duration": 1919000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T13:21:27", + "duration": 16713000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T18:00:00", + "duration": 7752000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T20:09:12", + "duration": 4951000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T21:31:43", + "duration": 1697000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T05:30:00", + "duration": 2075000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T06:04:35", + "duration": 5400000, + "percent": 1.4, + "rate": 2.17, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T07:34:35", + "duration": 3325000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T08:30:00", + "duration": 6166000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T10:12:46", + "duration": 5400000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T11:42:46", + "duration": 1034000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T22:00:00", + "duration": 4345000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T23:12:25", + "duration": 1767000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T23:41:52", + "duration": 1088000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T05:30:00", + "duration": 7632000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T07:37:12", + "duration": 7359000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T09:39:51", + "duration": 8409000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T08:30:00", + "duration": 7692000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T10:38:12", + "duration": 1864000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T11:09:16", + "duration": 3044000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T18:00:00", + "duration": 11017000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T21:03:37", + "duration": 10800000, + "percent": 1.5, + "rate": 1.72, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T22:00:00", + "duration": 10800000, + "percent": 1.5, + "rate": 1.95, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T00:00:00", + "duration": 10800000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T00:03:37", + "duration": 12383000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T05:30:00", + "duration": 5676000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T07:04:36", + "duration": 7200000, + "percent": 0.4, + "rate": 0.62, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T08:30:00", + "duration": 7200000, + "percent": 0.4, + "rate": 0.58, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T09:04:36", + "duration": 8062000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T11:18:58", + "duration": 3600000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T12:00:00", + "duration": 3600000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T12:18:58", + "duration": 20462000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T18:00:00", + "duration": 3789000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T19:03:09", + "duration": 4406000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T20:16:35", + "duration": 6205000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T12:00:00", + "duration": 21479000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T17:57:59", + "duration": 7200000, + "percent": 1.45, + "rate": 0.94, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T18:00:00", + "duration": 7200000, + "percent": 1.45, + "rate": 1.66, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.14, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T19:57:59", + "duration": 7321000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T03:30:00", + "duration": 6942000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:25:42", + "duration": 5400000, + "percent": 1.5, + "rate": 1.95, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:30:00", + "duration": 5400000, + "percent": 1.5, + "rate": 2.32, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T06:55:42", + "duration": 5658000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T18:00:00", + "duration": 12497000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T21:28:17", + "duration": 2135000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T22:03:52", + "duration": 6968000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T00:00:00", + "duration": 4032000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T01:07:12", + "duration": 7200000, + "percent": 1.75, + "rate": 2.53, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T03:07:12", + "duration": 1368000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T22:00:00", + "duration": 4835000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T23:20:35", + "duration": 5400000, + "percent": 1.5, + "rate": 1.95, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T00:00:00", + "duration": 5400000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T00:50:35", + "duration": 9565000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T05:30:00", + "duration": 1701000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T05:58:21", + "duration": 50296000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T19:56:37", + "duration": 7403000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T18:00:00", + "duration": 8649000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T20:24:09", + "duration": 9000000, + "percent": 1.95, + "rate": 2.24, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T22:00:00", + "duration": 9000000, + "percent": 1.95, + "rate": 2.53, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T22:54:09", + "duration": 3951000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T18:00:00", + "duration": 366000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T18:06:06", + "duration": 613000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T18:16:19", + "duration": 13421000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T03:30:00", + "duration": 5480000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:01:20", + "duration": 12600000, + "percent": 1.6, + "rate": 2.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:30:00", + "duration": 12600000, + "percent": 1.6, + "rate": 2.48, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T08:30:00", + "duration": 12600000, + "percent": 1.6, + "rate": 2.32, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T08:31:20", + "duration": 12520000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T05:30:00", + "duration": 3692000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T06:31:32", + "duration": 14400000, + "percent": 1.65, + "rate": 2.55, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T08:30:00", + "duration": 14400000, + "percent": 1.65, + "rate": 2.39, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T10:31:32", + "duration": 5308000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T18:00:00", + "duration": 9007000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T20:30:07", + "duration": 4826000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T21:50:33", + "duration": 567000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T12:00:00", + "duration": 175000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T12:02:55", + "duration": 203000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T12:06:18", + "duration": 21222000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T22:00:00", + "duration": 5252000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T23:27:32", + "duration": 7200000, + "percent": 1.45, + "rate": 1.88, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T00:00:00", + "duration": 7200000, + "percent": 1.45, + "rate": 2.1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T01:27:32", + "duration": 7348000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T05:30:00", + "duration": 10163000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T08:19:23", + "duration": 227000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T08:23:10", + "duration": 410000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T08:30:00", + "duration": 1916000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T09:01:56", + "duration": 291000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T09:06:47", + "duration": 10393000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T00:00:00", + "duration": 2058000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T00:34:18", + "duration": 18000000, + "percent": 1.3, + "rate": 1.88, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T03:30:00", + "duration": 18000000, + "percent": 1.3, + "rate": 1.69, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T05:30:00", + "duration": 18000000, + "percent": 1.3, + "rate": 2.01, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T05:34:18", + "duration": 10542000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T00:00:00", + "duration": 5352000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T01:29:12", + "duration": 16200000, + "percent": 1.45, + "rate": 2.1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T03:30:00", + "duration": 16200000, + "percent": 1.45, + "rate": 1.88, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T05:30:00", + "duration": 16200000, + "percent": 1.45, + "rate": 2.24, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T05:59:12", + "duration": 9048000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T08:30:00", + "duration": 10301000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T11:21:41", + "duration": 1674000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T11:49:35", + "duration": 625000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T12:00:00", + "duration": 10354000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T14:52:34", + "duration": 729000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T15:04:43", + "duration": 10517000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T05:30:00", + "duration": 6107000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T07:11:47", + "duration": 3600000, + "percent": 0.35, + "rate": 0.54, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T08:11:47", + "duration": 1093000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T08:30:00", + "duration": 5259000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T09:57:39", + "duration": 54000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T09:58:33", + "duration": 7287000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T22:00:00", + "duration": 4793000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T23:19:53", + "duration": 5171000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T00:46:04", + "duration": 9836000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T12:00:00", + "duration": 19060000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T17:17:40", + "duration": 298000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T17:22:38", + "duration": 2242000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T18:00:00", + "duration": 762000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T18:12:42", + "duration": 364000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T18:18:46", + "duration": 13274000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T08:30:00", + "duration": 3806000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T09:33:26", + "duration": 32400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T12:00:00", + "duration": 32400000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T18:00:00", + "duration": 32400000, + "percent": 0.75, + "rate": 0.86, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T18:33:26", + "duration": 12394000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T08:30:00", + "duration": 12207000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T11:53:27", + "duration": 10800000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T12:00:00", + "duration": 10800000, + "percent": 0.65, + "rate": 0.42, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T14:53:27", + "duration": 11193000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T00:00:00", + "duration": 4261000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T01:11:01", + "duration": 404000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T01:17:45", + "duration": 7935000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T08:30:00", + "duration": 1757000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T08:59:17", + "duration": 695000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T09:10:52", + "duration": 10148000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T12:00:00", + "duration": 18043000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T17:00:43", + "duration": 2404000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T17:40:47", + "duration": 1153000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T00:00:00", + "duration": 4572000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T01:16:12", + "duration": 303000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T01:21:15", + "duration": 7725000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T08:30:00", + "duration": 1219000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T08:50:19", + "duration": 5400000, + "percent": 1.3, + "rate": 1.88, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T10:20:19", + "duration": 5981000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T12:00:00", + "duration": 14758000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T16:05:58", + "duration": 375000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T16:12:13", + "duration": 6467000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T18:00:00", + "duration": 11599000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T21:13:19", + "duration": 711000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T21:25:10", + "duration": 2090000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T18:00:00", + "duration": 10305000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T20:51:45", + "duration": 7200000, + "percent": 0.19999999999999996, + "rate": 0.23, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T22:00:00", + "duration": 7200000, + "percent": 0.19999999999999996, + "rate": 0.28, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T22:51:45", + "duration": 4095000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T12:00:00", + "duration": 19370000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T17:22:50", + "duration": 3600000, + "percent": 0.7, + "rate": 0.45, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T18:00:00", + "duration": 3600000, + "percent": 0.7, + "rate": 0.8, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.14, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T18:22:50", + "duration": 13030000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T03:30:00", + "duration": 7580000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T05:36:20", + "duration": 249000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T05:40:29", + "duration": 10171000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T08:30:00", + "duration": 169000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T08:32:49", + "duration": 544000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T08:41:53", + "duration": 11887000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T12:00:00", + "duration": 16275000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T16:31:15", + "duration": 455000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T16:38:50", + "duration": 4870000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T18:00:00", + "duration": 13413000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T21:43:33", + "duration": 246000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T21:47:39", + "duration": 741000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:00:00", + "duration": 643000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:10:43", + "duration": 60000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:10:50", + "duration": 273000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:15:23", + "duration": 28000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:15:51", + "duration": 7200000, + "percent": 1.3, + "rate": 1.95, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T02:15:51", + "duration": 4449000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T00:00:00", + "duration": 10840000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:00:40", + "duration": 10800000, + "percent": 1.45, + "rate": 2.17, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:30:00", + "duration": 10800000, + "percent": 1.45, + "rate": 1.95, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.34, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T05:30:00", + "duration": 10800000, + "percent": 1.45, + "rate": 2.24, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T06:00:40", + "duration": 8960000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T05:30:00", + "duration": 9662000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T08:11:02", + "duration": 6831000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T10:04:53", + "duration": 973000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T10:21:06", + "duration": 97000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T10:22:43", + "duration": 5837000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T12:00:00", + "duration": 4664000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T13:17:44", + "duration": 7380000, + "percent": 1.5, + "rate": 0.97, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T15:19:49", + "duration": 9611000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T22:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T22:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T22:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T05:30:00", + "duration": 7957000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T07:42:37", + "duration": 35000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T07:43:12", + "duration": 2808000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T08:30:00", + "duration": 8781000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T10:56:21", + "duration": 254000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T11:00:35", + "duration": 3565000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T00:00:00", + "duration": 4542000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T01:15:42", + "duration": 10800000, + "percent": 0.7, + "rate": 1.05, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T03:30:00", + "duration": 10800000, + "percent": 0.7, + "rate": 0.94, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.34, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T04:15:42", + "duration": 4458000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T18:00:00", + "duration": 366000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T18:06:06", + "duration": 21600000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T22:00:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T00:00:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T00:06:06", + "duration": 9204000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T02:39:30", + "duration": 18000000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T03:30:00", + "duration": 18000000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.35, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T05:30:00", + "duration": 18000000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T07:39:30", + "duration": 3030000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T08:30:00", + "duration": 8164000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T10:46:04", + "duration": 18000000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T12:00:00", + "duration": 18000000, + "percent": 0.65, + "rate": 0.42, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T15:46:04", + "duration": 8036000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T12:00:00", + "duration": 21410000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T17:56:50", + "duration": 2163000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T18:32:53", + "duration": 12427000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T22:00:00", + "duration": 5415000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T23:30:15", + "duration": 7200000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T00:00:00", + "duration": 7200000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T01:30:15", + "duration": 7185000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T08:30:00", + "duration": 345000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T08:35:45", + "duration": 5400000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T10:05:45", + "duration": 6855000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T18:00:00", + "duration": 9705000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T20:41:45", + "duration": 7200000, + "percent": 1.3, + "rate": 1.49, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T22:00:00", + "duration": 7200000, + "percent": 1.3, + "rate": 1.88, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T22:41:45", + "duration": 4695000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T00:00:00", + "duration": 5211000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T01:26:51", + "duration": 199000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T01:30:10", + "duration": 147000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T01:32:37", + "duration": 12600000, + "percent": 0.75, + "rate": 1.12, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.49, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T03:30:00", + "duration": 12600000, + "percent": 0.75, + "rate": 1.01, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.35, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T05:02:37", + "duration": 1643000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T12:00:00", + "duration": 91000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T12:01:31", + "duration": 7200000, + "percent": 1.35, + "rate": 0.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T14:01:31", + "duration": 14309000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T00:00:00", + "duration": 8771000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T02:26:11", + "duration": 272000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T02:30:43", + "duration": 3557000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T08:30:00", + "duration": 5906000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T10:08:26", + "duration": 2274000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T10:46:20", + "duration": 4420000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T18:00:00", + "duration": 2434000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T18:40:34", + "duration": 3332000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T19:36:06", + "duration": 8634000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T22:00:00", + "duration": 7042000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T23:57:22", + "duration": 114000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T23:59:16", + "duration": 44000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T08:30:00", + "duration": 135000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T08:32:15", + "duration": 360000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T09:38:15", + "duration": 8505000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T00:00:00", + "duration": 5721000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T01:35:21", + "duration": 660000, + "percent": 0.6, + "rate": 0.9, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T01:45:59", + "duration": 6241000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T18:00:00", + "duration": 12763000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T21:32:43", + "duration": 200000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T21:36:03", + "duration": 1437000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T00:00:00", + "duration": 7717000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T02:08:37", + "duration": 9000000, + "percent": 1.2, + "rate": 1.8, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T03:30:00", + "duration": 9000000, + "percent": 1.2, + "rate": 1.62, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.35, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T04:38:37", + "duration": 3083000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T00:00:00", + "duration": 1387000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T00:23:07", + "duration": 5575000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T01:56:02", + "duration": 5638000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T00:00:00", + "duration": 5074000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T01:24:34", + "duration": 3600000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T02:24:34", + "duration": 3926000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T12:00:00", + "duration": 14636000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T16:03:56", + "duration": 156000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T16:06:32", + "duration": 6808000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T12:00:00", + "duration": 261000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T12:04:21", + "duration": 241000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T12:08:22", + "duration": 21098000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T08:30:00", + "duration": 5750000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T10:05:50", + "duration": 188000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T10:08:58", + "duration": 6662000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T12:00:00", + "duration": 17191000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T16:46:31", + "duration": 4727000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T18:05:18", + "duration": 14082000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T18:00:00", + "duration": 2581000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T18:43:01", + "duration": 67000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T21:44:08", + "duration": 952000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T18:00:00", + "duration": 9738000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T20:42:18", + "duration": 1004000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T20:59:02", + "duration": 3658000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T00:00:00", + "duration": 12403000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:26:43", + "duration": 7200000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:30:00", + "duration": 7200000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.35, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T05:26:43", + "duration": 197000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T18:00:00", + "duration": 3804000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T19:03:24", + "duration": 476000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T19:11:20", + "duration": 10120000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T08:30:00", + "duration": 3078000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T09:21:18", + "duration": 5400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T10:51:18", + "duration": 4122000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T18:00:00", + "duration": 8562000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T20:22:42", + "duration": 87000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T17:24:09", + "duration": 2151000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T18:00:00", + "duration": 10423000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T20:53:43", + "duration": 2326000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T21:32:29", + "duration": 1651000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T08:30:00", + "duration": 11164000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T11:36:04", + "duration": 7381000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T13:39:05", + "duration": 15655000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T18:00:00", + "duration": 6679000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T19:51:19", + "duration": 1653000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T20:18:52", + "duration": 6068000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T08:30:00", + "duration": 6131000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T10:12:11", + "duration": 1800000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T10:42:11", + "duration": 4669000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T12:00:00", + "duration": 243000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T12:04:03", + "duration": 36000000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T18:00:00", + "duration": 36000000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T22:00:00", + "duration": 36000000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T22:04:02", + "duration": 6958000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T08:30:00", + "duration": 321000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T08:35:21", + "duration": 28800000, + "percent": 0.7, + "rate": 1.01, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T12:00:00", + "duration": 28200000, + "percent": 0.7, + "rate": 0.45, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T16:25:06", + "duration": 17000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T16:25:23", + "duration": 12600000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T18:00:00", + "duration": 12600000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T19:55:23", + "duration": 7477000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T22:00:00", + "duration": 5512000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T23:31:52", + "duration": 351000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T23:37:43", + "duration": 562000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T23:47:05", + "duration": 36000000, + "percent": 0.6, + "rate": 0.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:00:00", + "duration": 840000, + "percent": 0.6, + "rate": 0.9, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:01:02", + "duration": 13000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:01:15", + "duration": 10380000, + "percent": 0.5, + "rate": 0.75, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T02:54:02", + "duration": 17000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T02:54:19", + "duration": 27000000, + "percent": 0.35, + "rate": 0.52, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.49, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T03:30:00", + "duration": 27000000, + "percent": 0.35, + "rate": 0.47, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.34, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T05:30:00", + "duration": 14700000, + "percent": 0.35, + "rate": 0.54, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T06:59:14", + "duration": 5446000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T08:30:00", + "duration": 1684000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T08:58:04", + "duration": 3600000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T09:58:04", + "duration": 211000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T10:01:35", + "duration": 3600000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T11:01:35", + "duration": 3505000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T12:00:00", + "duration": 1514000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T12:25:14", + "duration": 12840000, + "percent": 0.55, + "rate": 0.35, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T15:58:44", + "duration": 8000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T15:58:52", + "duration": 5400000, + "percent": 1.25, + "rate": 0.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T17:28:52", + "duration": 1868000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T18:00:00", + "duration": 4291000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T19:11:31", + "duration": 60000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T19:12:19", + "duration": 10061000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T00:00:00", + "duration": 2499000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T00:41:39", + "duration": 7200000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T02:41:39", + "duration": 2901000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T05:30:00", + "duration": 10759000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T08:29:19", + "duration": 4125000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T09:38:04", + "duration": 8516000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T12:00:00", + "duration": 4493000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T13:14:53", + "duration": 3600000, + "percent": 0.9, + "rate": 0.58, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T14:14:53", + "duration": 13507000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T05:30:00", + "duration": 8560000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T07:52:40", + "duration": 8961000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T10:22:01", + "duration": 5879000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T22:00:00", + "duration": 6208000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T23:43:28", + "duration": 7200000, + "percent": 1.1, + "rate": 1.59, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T00:00:00", + "duration": 7200000, + "percent": 1.1, + "rate": 1.65, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T01:43:28", + "duration": 6392000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T12:00:00", + "duration": 11187000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T15:06:27", + "duration": 3600000, + "percent": 0.7, + "rate": 0.45, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T16:06:27", + "duration": 6813000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T08:30:00", + "duration": 7374000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T10:32:54", + "duration": 790000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T10:46:04", + "duration": 4436000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T05:30:00", + "duration": 10425000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T08:23:45", + "duration": 375000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T12:00:00", + "duration": 10788000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T14:59:48", + "duration": 3678000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T16:01:06", + "duration": 7134000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T12:00:00", + "duration": 9679000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T14:41:19", + "duration": 10800000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T17:41:19", + "duration": 1121000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T22:00:00", + "duration": 4227000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T23:10:27", + "duration": 586000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T23:20:13", + "duration": 2387000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T18:00:00", + "duration": 13412000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T21:43:32", + "duration": 200000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T21:46:52", + "duration": 788000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T00:00:00", + "duration": 3746000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:02:26", + "duration": 180000, + "percent": 0.7, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:04:34", + "duration": 11000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:04:45", + "duration": 18000000, + "percent": 0.85, + "rate": 1.31, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T03:30:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.19, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T05:30:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.36, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T06:04:45", + "duration": 8715000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T00:00:00", + "duration": 10498000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T02:54:58", + "duration": 21600000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T03:30:00", + "duration": 21600000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T05:30:00", + "duration": 21600000, + "percent": 0.75, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T08:30:00", + "duration": 21600000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T08:54:58", + "duration": 11102000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T22:00:00", + "duration": 4513000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T23:15:13", + "duration": 147000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T23:17:40", + "duration": 2540000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T00:00:00", + "duration": 635000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T00:10:35", + "duration": 315000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T00:15:50", + "duration": 11650000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T18:00:00", + "duration": 1631000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T18:27:11", + "duration": 3420000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T19:24:10", + "duration": 9350000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T05:30:00", + "duration": 3903000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T06:35:03", + "duration": 7200000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T08:30:00", + "duration": 7200000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T08:35:03", + "duration": 2092000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T09:09:55", + "duration": 43200000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T12:00:00", + "duration": 16200000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T13:39:54", + "duration": 221000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T13:43:35", + "duration": 10550000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T16:39:25", + "duration": 21498000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T22:37:43", + "duration": 4937000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T00:00:00", + "duration": 5097000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T01:24:57", + "duration": 30600000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T03:30:00", + "duration": 30600000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.35, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T05:30:00", + "duration": 30600000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T08:30:00", + "duration": 30600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T09:54:57", + "duration": 4178000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T11:04:35", + "duration": 41400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T12:00:00", + "duration": 41400000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T18:00:00", + "duration": 41400000, + "percent": 0.75, + "rate": 0.86, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T22:00:00", + "duration": 41400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T22:34:35", + "duration": 5125000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T00:00:00", + "duration": 4232000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T01:10:32", + "duration": 28800000, + "percent": 0.75, + "rate": 1.12, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.49, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T03:30:00", + "duration": 28800000, + "percent": 0.75, + "rate": 1.01, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.35, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T05:30:00", + "duration": 28800000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T08:30:00", + "duration": 28800000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T09:10:32", + "duration": 10168000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T05:30:00", + "duration": 10250000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:20:50", + "duration": 28800000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:30:00", + "duration": 28800000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T12:00:00", + "duration": 28800000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T16:20:50", + "duration": 5950000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T18:00:00", + "duration": 9910000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T20:45:10", + "duration": 257000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T20:49:27", + "duration": 4233000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T03:30:00", + "duration": 4311000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T04:41:51", + "duration": 18428000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T09:48:59", + "duration": 7861000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T18:00:00", + "duration": 11857000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T21:17:37", + "duration": 10800000, + "percent": 1.15, + "rate": 1.32, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T22:00:00", + "duration": 5460000, + "percent": 1.15, + "rate": 1.66, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T22:48:11", + "duration": 2421000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T23:28:32", + "duration": 3600000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T00:00:00", + "duration": 3600000, + "percent": 1.25, + "rate": 1.93, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T00:28:32", + "duration": 10888000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T12:00:00", + "duration": 21052000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T17:50:52", + "duration": 10800000, + "percent": 1.25, + "rate": 0.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T18:00:00", + "duration": 10800000, + "percent": 1.25, + "rate": 1.43, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.14, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T20:50:52", + "duration": 4148000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T05:30:00", + "duration": 1821000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T06:00:21", + "duration": 217000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T06:03:58", + "duration": 8762000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T18:00:00", + "duration": 2689000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T18:44:49", + "duration": 3986000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T19:51:15", + "duration": 7725000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T18:00:00", + "duration": 8609000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T20:23:29", + "duration": 9000000, + "percent": 1.5, + "rate": 1.72, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T22:00:00", + "duration": 7140000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T22:21:32", + "duration": 5908000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T12:00:00", + "duration": 16133000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T16:28:53", + "duration": 113000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T16:30:46", + "duration": 5354000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T12:00:00", + "duration": 19563000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T17:26:03", + "duration": 368000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T17:32:11", + "duration": 1669000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T22:00:00", + "duration": 1859000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T22:30:59", + "duration": 3600000, + "percent": 1.95, + "rate": 2.82, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T23:30:59", + "duration": 1741000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T08:30:00", + "duration": 8897000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T10:58:17", + "duration": 1755000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T11:27:32", + "duration": 1948000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T12:00:00", + "duration": 19655000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T17:27:35", + "duration": 375000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T17:33:50", + "duration": 1570000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T18:00:00", + "duration": 13374000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T21:42:54", + "duration": 10800000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T22:00:00", + "duration": 10800000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T00:00:00", + "duration": 10800000, + "percent": 1.4, + "rate": 2.1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T00:42:54", + "duration": 10026000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T08:30:00", + "duration": 11426000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T11:40:26", + "duration": 7949000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T13:52:55", + "duration": 14825000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T08:30:00", + "duration": 2522000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T09:12:02", + "duration": 14514000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T13:13:56", + "duration": 17164000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T18:00:00", + "duration": 14339000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T21:58:59", + "duration": 1800000, + "percent": 0.09999999999999998, + "rate": 0.11, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.1, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T22:00:00", + "duration": 1800000, + "percent": 0.09999999999999998, + "rate": 0.14, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T22:28:59", + "duration": 5461000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T12:00:00", + "duration": 20380000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T17:39:40", + "duration": 3600000, + "percent": 0.65, + "rate": 0.42, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T18:00:00", + "duration": 3600000, + "percent": 0.65, + "rate": 0.74, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.14, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T18:39:40", + "duration": 12020000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T22:00:00", + "duration": 1941000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T22:32:21", + "duration": 332000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T22:37:53", + "duration": 4927000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T00:00:00", + "duration": 7844000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T02:10:44", + "duration": 5400000, + "percent": 0.6, + "rate": 0.9, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T03:30:00", + "duration": 5400000, + "percent": 0.6, + "rate": 0.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.35, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T03:40:44", + "duration": 6556000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T22:00:00", + "duration": 89000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T22:01:29", + "duration": 427000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T22:08:36", + "duration": 6684000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T12:00:00", + "duration": 6521000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:48:41", + "duration": 180000, + "percent": 0.6, + "rate": 0.39, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:51:15", + "duration": 329000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:56:44", + "duration": 5400000, + "percent": 1.2, + "rate": 0.78, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T15:26:44", + "duration": 9196000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T00:00:00", + "duration": 2718000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T00:45:18", + "duration": 410000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T00:52:08", + "duration": 9472000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T18:00:00", + "duration": 9098000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T20:31:38", + "duration": 238000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T20:35:36", + "duration": 5064000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T12:00:00", + "duration": 6090000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T13:41:30", + "duration": 277000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T13:46:07", + "duration": 8525000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-07T15:08:12", + "duration": 13000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T16:08:25", + "duration": 10295000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-07T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T12:00:00", + "duration": 537000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T12:08:57", + "duration": 190000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T12:12:07", + "duration": 20873000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T12:00:00", + "duration": 3798000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T13:03:18", + "duration": 482000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T14:12:18", + "duration": 13662000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T03:30:00", + "duration": 3971000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T04:36:11", + "duration": 250000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T04:40:21", + "duration": 2979000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T22:00:00", + "duration": 3091000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T22:51:31", + "duration": 1929000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T23:23:40", + "duration": 2180000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T12:00:00", + "duration": 2125000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T12:35:25", + "duration": 1737000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T13:04:22", + "duration": 17738000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T00:00:00", + "duration": 1723000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T00:28:43", + "duration": 27000000, + "percent": 0.65, + "rate": 0.97, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.49, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T03:30:00", + "duration": 27000000, + "percent": 0.65, + "rate": 0.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.34, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T05:30:00", + "duration": 27000000, + "percent": 0.65, + "rate": 1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T07:58:43", + "duration": 1877000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T12:00:00", + "duration": 11186000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T15:06:26", + "duration": 10709000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T18:04:55", + "duration": 14105000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T08:30:00", + "duration": 7555000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T10:35:55", + "duration": 27000000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T12:00:00", + "duration": 27000000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T18:00:00", + "duration": 27000000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T18:05:54", + "duration": 6111000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T19:47:45", + "duration": 18000000, + "percent": 0.85, + "rate": 0.97, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.14, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T22:00:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.23, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T00:00:00", + "duration": 17880000, + "percent": 0.85, + "rate": 1.27, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.49, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T00:44:56", + "duration": 112000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T00:46:48", + "duration": 9792000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T18:00:00", + "duration": 10769000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T20:59:29", + "duration": 3631000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T08:30:00", + "duration": 10621000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T11:27:01", + "duration": 25200000, + "percent": 0.8, + "rate": 1.12, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T12:00:00", + "duration": 14160000, + "percent": 0.8, + "rate": 0.48, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T15:22:15", + "duration": 52000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T18:23:07", + "duration": 13013000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T22:00:00", + "duration": 6238000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T23:43:58", + "duration": 870000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T23:58:28", + "duration": 92000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T00:00:00", + "duration": 9249000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T02:34:09", + "duration": 9000000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T03:30:00", + "duration": 9000000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.35, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T05:04:09", + "duration": 1551000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T08:30:00", + "duration": 6845000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T10:24:05", + "duration": 10800000, + "percent": 1.35, + "rate": 1.89, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T12:00:00", + "duration": 10800000, + "percent": 1.35, + "rate": 0.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T13:24:05", + "duration": 16555000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T05:30:00", + "duration": 8167000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T07:46:07", + "duration": 5319000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T09:14:46", + "duration": 9914000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T22:00:00", + "duration": 2939000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T22:48:59", + "duration": 3600000, + "percent": 0.85, + "rate": 1.19, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T23:48:59", + "duration": 661000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T00:00:00", + "duration": 10930000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T03:02:10", + "duration": 56000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T00:03:06", + "duration": 12414000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T12:00:00", + "duration": 16156000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T16:29:16", + "duration": 5400000, + "percent": 1.4, + "rate": 0.84, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T17:59:16", + "duration": 44000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T12:00:00", + "duration": 7901000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T14:11:41", + "duration": 1866000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T14:42:47", + "duration": 11833000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T08:30:00", + "duration": 7554000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T10:35:54", + "duration": 27000000, + "percent": 0.85, + "rate": 1.19, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T12:00:00", + "duration": 27000000, + "percent": 0.85, + "rate": 0.51, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T18:00:00", + "duration": 27000000, + "percent": 0.85, + "rate": 0.89, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T18:05:54", + "duration": 14046000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T22:00:00", + "duration": 5283000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T23:28:03", + "duration": 3855000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T00:32:18", + "duration": 10662000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T18:00:00", + "duration": 6951000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T19:55:51", + "duration": 7449000, + "rate": 1, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T22:00:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T05:30:00", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T08:30:00", + "duration": 10564000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T11:26:04", + "duration": 139000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T11:28:23", + "duration": 1897000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T00:00:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T03:30:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T00:00:00", + "duration": 11060000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:04:20", + "duration": 21600000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:30:00", + "duration": 21600000, + "percent": 0.75, + "rate": 0.93, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.24, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T05:30:00", + "duration": 19560000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T08:27:11", + "duration": 10538000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T11:22:49", + "duration": 2231000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T00:00:00", + "duration": 10459000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T02:54:19", + "duration": 7200000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T03:30:00", + "duration": 7200000, + "percent": 0.75, + "rate": 0.93, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.24, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T04:54:19", + "duration": 2141000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T00:00:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T03:30:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T00:00:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T03:30:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T18:00:00", + "duration": 4501000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T19:15:01", + "duration": 442000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T19:22:23", + "duration": 9457000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T00:00:00", + "duration": 9207000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T02:33:27", + "duration": 3600000, + "percent": 1.35, + "rate": 1.89, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T03:30:00", + "duration": 3600000, + "percent": 1.35, + "rate": 1.68, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.24, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T03:33:27", + "duration": 6993000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T00:00:00", + "duration": 7931000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T02:12:11", + "duration": 1802000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T02:42:13", + "duration": 2867000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T00:00:00", + "duration": 1644000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T00:27:24", + "duration": 387000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T00:33:51", + "duration": 10569000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T05:30:00", + "duration": 11850000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T08:47:30", + "duration": 7734000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T10:56:24", + "duration": 3816000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T12:00:00", + "duration": 11503000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T15:11:43", + "duration": 238000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T15:15:41", + "duration": 9859000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T00:00:00", + "duration": 11695000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:14:55", + "duration": 18000000, + "percent": 0.85, + "rate": 1.1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.29, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:30:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.02, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.2, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T05:30:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.29, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T08:14:55", + "duration": 905000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T08:30:00", + "duration": 4149000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T09:39:09", + "duration": 6405000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T11:25:54", + "duration": 2046000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T12:00:00", + "duration": 10914000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T15:01:54", + "duration": 3600000, + "percent": 1.25, + "rate": 0.56, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T16:01:54", + "duration": 7086000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T12:00:00", + "duration": 14774000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T16:06:14", + "duration": 789000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T16:19:23", + "duration": 6037000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T18:00:00", + "duration": 5447000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T19:30:47", + "duration": 10800000, + "percent": 1.15, + "rate": 1.03, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.9, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T22:00:00", + "duration": 10800000, + "percent": 1.15, + "rate": 1.43, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.24, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T22:30:47", + "duration": 5353000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T00:00:00", + "duration": 7351000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T02:02:31", + "duration": 5400000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T03:30:00", + "duration": 5400000, + "percent": 0.8, + "rate": 0.96, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.2, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T03:32:31", + "duration": 7049000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T00:00:00", + "duration": 829000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T00:13:49", + "duration": 2232000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T00:51:01", + "duration": 9539000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T08:30:00", + "duration": 1596000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T08:56:36", + "duration": 882000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T09:11:18", + "duration": 10122000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T18:00:00", + "duration": 124000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T18:02:04", + "duration": 5400000, + "percent": 0.85, + "rate": 0.76, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.89, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T19:32:04", + "duration": 8876000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T00:00:00", + "duration": 860000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T00:14:20", + "duration": 2644000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T00:58:24", + "duration": 9096000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T18:00:00", + "duration": 1335000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T18:22:15", + "duration": 5400000, + "percent": 0.4, + "rate": 0.36, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.9, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T19:52:15", + "duration": 7665000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T00:00:00", + "duration": 7906000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T02:11:46", + "duration": 21445000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T08:09:11", + "duration": 1249000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T00:00:00", + "duration": 6044000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T01:40:44", + "duration": 5880000, + "percent": 0.85, + "rate": 1.1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.29, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:18:31", + "duration": 9000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:18:40", + "duration": 7200000, + "percent": 0.7, + "rate": 0.91, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:30:00", + "duration": 7200000, + "percent": 0.7, + "rate": 0.84, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.2, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T05:18:40", + "duration": 680000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T12:00:00", + "duration": 8453000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T14:20:53", + "duration": 326000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T14:26:19", + "duration": 12821000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T12:00:00", + "duration": 18803000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T17:13:23", + "duration": 7200000, + "percent": 1.25, + "rate": 0.56, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T18:00:00", + "duration": 7200000, + "percent": 1.25, + "rate": 1.12, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.9, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T19:13:23", + "duration": 9106000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T21:45:09", + "duration": 251000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T21:49:20", + "duration": 640000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T05:30:00", + "duration": 9183000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T08:03:03", + "duration": 1617000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T03:30:00", + "duration": 5472000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T05:01:12", + "duration": 180000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T05:04:12", + "duration": 1548000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T18:00:00", + "duration": 13178000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T21:39:38", + "duration": 3600000, + "percent": 1.15, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.04, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T22:00:00", + "duration": 3600000, + "percent": 1.15, + "rate": 1.61, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T22:39:38", + "duration": 4822000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T12:00:00", + "duration": 4236000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T13:10:36", + "duration": 3620000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T14:10:56", + "duration": 3631000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T15:11:27", + "duration": 600000, + "percent": 0.8, + "rate": 0.48, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T15:21:15", + "duration": 7934000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T17:33:29", + "duration": 1591000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T00:00:00", + "duration": 8499000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T02:21:39", + "duration": 16200000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T03:30:00", + "duration": 16200000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.35, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T05:30:00", + "duration": 16200000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T06:51:39", + "duration": 5901000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T18:00:00", + "duration": 3812000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T19:03:32", + "duration": 6060000, + "percent": 0.75, + "rate": 0.78, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.04, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T20:44:03", + "duration": 9000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T20:44:12", + "duration": 5400000, + "percent": 0.65, + "rate": 0.68, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T22:00:00", + "duration": 5400000, + "percent": 0.65, + "rate": 0.91, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T22:14:12", + "duration": 6348000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T08:30:00", + "duration": 7596000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T10:36:36", + "duration": 5004000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T18:00:00", + "duration": 57000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T18:00:57", + "duration": 10800000, + "percent": 0.19999999999999996, + "rate": 0.18, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.9, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T21:00:57", + "duration": 2953000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T21:50:10", + "duration": 240000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T21:54:10", + "duration": 350000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T05:30:00", + "duration": 1539000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T05:55:39", + "duration": 255000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T05:59:54", + "duration": 9006000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T12:00:00", + "duration": 19916000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T17:31:56", + "duration": 9000000, + "percent": 0.6, + "rate": 0.27, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T18:00:00", + "duration": 9000000, + "percent": 0.6, + "rate": 0.54, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.9, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T20:01:56", + "duration": 7084000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T12:00:00", + "duration": 12721000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T15:32:01", + "duration": 1800000, + "percent": 0.7, + "rate": 0.31, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T16:02:01", + "duration": 7079000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T12:00:00", + "duration": 6854000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T13:54:14", + "duration": 473000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T14:02:07", + "duration": 14273000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T00:00:00", + "duration": 11831000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:17:11", + "duration": 25200000, + "percent": 0.75, + "rate": 0.97, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.29, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:30:00", + "duration": 25200000, + "percent": 0.75, + "rate": 0.9, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.2, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T05:30:00", + "duration": 25200000, + "percent": 0.75, + "rate": 0.97, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.29, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T08:30:00", + "duration": 25200000, + "percent": 0.75, + "rate": 0.93, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.24, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T10:17:11", + "duration": 6169000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T00:00:00", + "duration": 7034000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T01:57:14", + "duration": 25200000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T03:30:00", + "duration": 25200000, + "percent": 0.8, + "rate": 0.96, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.2, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T05:30:00", + "duration": 25200000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T08:30:00", + "duration": 25200000, + "percent": 0.8, + "rate": 1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.25, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T08:57:14", + "duration": 10966000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T12:00:00", + "duration": 8532000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T14:22:12", + "duration": 7200000, + "percent": 0.30000000000000004, + "rate": 0.13, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.43, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T16:22:12", + "duration": 5868000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T18:00:00", + "duration": 14095000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T21:54:55", + "duration": 280000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T21:59:35", + "duration": 25000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T03:30:00", + "duration": 6075000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T05:11:15", + "duration": 397000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T05:17:52", + "duration": 728000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T12:00:00", + "duration": 4392000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T13:13:12", + "duration": 17592000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T18:06:24", + "duration": 14016000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T08:30:00", + "duration": 9169000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T11:02:49", + "duration": 3431000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T05:30:00", + "duration": 4177000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T06:39:37", + "duration": 10025000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T09:26:42", + "duration": 9198000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T12:00:00", + "duration": 19217000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T17:20:17", + "duration": 6688000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T19:11:45", + "duration": 10095000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T00:00:00", + "duration": 1827000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T00:30:27", + "duration": 1374000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T00:53:21", + "duration": 9399000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T08:30:00", + "duration": 2264000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T09:07:44", + "duration": 7415000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T11:11:19", + "duration": 1593000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T11:37:52", + "duration": 5400000, + "percent": 1.35, + "rate": 1.89, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T12:00:00", + "duration": 5400000, + "percent": 1.35, + "rate": 0.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T13:07:52", + "duration": 17528000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T12:00:00", + "duration": 142000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T12:02:22", + "duration": 3600000, + "percent": 0.7, + "rate": 0.42, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T13:02:22", + "duration": 17858000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T08:30:00", + "duration": 5863000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T10:07:43", + "duration": 5400000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T11:37:43", + "duration": 1337000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T18:00:00", + "duration": 4181000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T19:09:41", + "duration": 3495000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T20:07:56", + "duration": 6724000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T12:00:00", + "duration": 5103000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T13:25:03", + "duration": 76000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T13:26:19", + "duration": 16421000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T18:00:00", + "duration": 13638000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T21:47:18", + "duration": 533000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T21:56:11", + "duration": 229000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T18:00:00", + "duration": 2999000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T18:49:59", + "duration": 3600000, + "percent": 1.45, + "rate": 1.52, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T19:49:59", + "duration": 7801000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T00:00:00", + "duration": 2319000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T00:38:39", + "duration": 7200000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T02:38:39", + "duration": 3081000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T00:00:00", + "duration": 1518000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T00:25:18", + "duration": 3600000, + "percent": 0.7, + "rate": 1.05, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T01:25:18", + "duration": 7482000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T05:30:00", + "duration": 1230000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T05:50:30", + "duration": 18830000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T11:04:20", + "duration": 3340000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T12:00:00", + "duration": 19246000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T17:20:46", + "duration": 7200000, + "percent": 1.7, + "rate": 1.02, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T18:00:00", + "duration": 7200000, + "percent": 1.7, + "rate": 1.78, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T19:20:46", + "duration": 9554000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T08:30:00", + "duration": 2085000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T09:04:45", + "duration": 4217000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T10:15:02", + "duration": 6298000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T12:00:00", + "duration": 17944000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T16:59:04", + "duration": 3600000, + "percent": 1.65, + "rate": 0.99, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T17:59:04", + "duration": 56000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T18:00:00", + "duration": 5666000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T19:34:26", + "duration": 5400000, + "percent": 1.9, + "rate": 1.99, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T21:04:26", + "duration": 3334000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T00:00:00", + "duration": 2082000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T00:34:42", + "duration": 3600000, + "percent": 1.35, + "rate": 2.02, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T01:34:42", + "duration": 6918000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T12:00:00", + "duration": 5752000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T13:35:52", + "duration": 204000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T13:39:16", + "duration": 5345000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T15:08:21", + "duration": 5400000, + "percent": 1.55, + "rate": 0.93, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T16:38:21", + "duration": 4899000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T18:00:00", + "duration": 6720000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T19:52:00", + "duration": 645000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T20:02:45", + "duration": 7035000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T05:30:00", + "duration": 9805000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:13:25", + "duration": 5400000, + "percent": 1.5, + "rate": 2.32, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:30:00", + "duration": 5400000, + "percent": 1.5, + "rate": 2.1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T09:43:25", + "duration": 8195000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T12:00:00", + "duration": 2532000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T12:42:12", + "duration": 4620000, + "percent": 1.4, + "rate": 0.84, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T13:58:48", + "duration": 14000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T13:59:02", + "duration": 5400000, + "percent": 1.55, + "rate": 0.93, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T15:29:02", + "duration": 6819000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T17:22:41", + "duration": 7200000, + "percent": 1.35, + "rate": 0.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T18:00:00", + "duration": 7200000, + "percent": 1.35, + "rate": 1.41, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.04, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T19:22:41", + "duration": 9439000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T00:00:00", + "duration": 9113000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T02:31:53", + "duration": 5400000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T03:30:00", + "duration": 5400000, + "percent": 1.25, + "rate": 1.68, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.34, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T04:01:53", + "duration": 5287000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T08:30:00", + "duration": 4914000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T09:51:54", + "duration": 9000000, + "percent": 0.8, + "rate": 1.12, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T12:00:00", + "duration": 9000000, + "percent": 0.8, + "rate": 0.48, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T12:21:54", + "duration": 20286000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T18:00:00", + "duration": 1416000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T18:23:36", + "duration": 10800000, + "percent": 1.5, + "rate": 1.57, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T21:23:36", + "duration": 2184000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T08:30:00", + "duration": 3040000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T09:20:40", + "duration": 3159000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T10:13:19", + "duration": 6401000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T12:00:00", + "duration": 4788000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T13:19:48", + "duration": 7200000, + "percent": 1.45, + "rate": 0.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T15:19:48", + "duration": 4339000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T16:32:07", + "duration": 7200000, + "percent": 1.5, + "rate": 0.9, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T18:00:00", + "duration": 7200000, + "percent": 1.5, + "rate": 1.57, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T18:32:07", + "duration": 12473000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T18:00:00", + "duration": 4755000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T19:19:15", + "duration": 9000000, + "percent": 1.5, + "rate": 1.57, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T21:49:15", + "duration": 645000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T18:00:00", + "duration": 12431000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T21:27:11", + "duration": 10800000, + "percent": 1.95, + "rate": 2.04, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T22:00:00", + "duration": 10800000, + "percent": 1.95, + "rate": 2.73, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T00:00:00", + "duration": 10800000, + "percent": 1.95, + "rate": 2.92, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T00:27:11", + "duration": 10969000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T18:00:00", + "duration": 260000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T18:04:20", + "duration": 3314000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T18:59:34", + "duration": 7000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T18:59:41", + "duration": 45000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T19:00:26", + "duration": 10774000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T05:30:00", + "duration": 7859000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T07:40:59", + "duration": 36000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T07:41:35", + "duration": 2905000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T08:30:00", + "duration": 5764000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T10:06:04", + "duration": 7200000, + "percent": 1.25, + "rate": 1.75, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T12:00:00", + "duration": 7200000, + "percent": 1.25, + "rate": 0.75, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T12:06:04", + "duration": 21236000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T08:30:00", + "duration": 11084000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T11:34:44", + "duration": 3600000, + "percent": 0.7, + "rate": 0.98, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T12:00:00", + "duration": 3600000, + "percent": 0.7, + "rate": 0.42, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T12:34:44", + "duration": 19516000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T12:00:00", + "duration": 12872000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T15:34:32", + "duration": 4983000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T16:57:35", + "duration": 3745000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T18:00:00", + "duration": 5583000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T19:33:03", + "duration": 7200000, + "percent": 1.55, + "rate": 1.62, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T21:33:03", + "duration": 1617000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T00:00:00", + "duration": 2776000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T00:46:16", + "duration": 7200000, + "percent": 1.3, + "rate": 2.01, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T02:46:16", + "duration": 2624000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T22:00:00", + "duration": 1978000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T22:32:58", + "duration": 14400000, + "percent": 1.75, + "rate": 2.45, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T00:00:00", + "duration": 14400000, + "percent": 1.75, + "rate": 2.71, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T02:32:58", + "duration": 3422000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T05:30:00", + "duration": 8216000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T07:46:56", + "duration": 670000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T07:58:06", + "duration": 9000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T07:58:15", + "duration": 3600000, + "percent": 1.45, + "rate": 2.24, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T08:30:00", + "duration": 3600000, + "percent": 1.45, + "rate": 2.03, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T08:58:15", + "duration": 10905000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T18:00:00", + "duration": 1977000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T18:32:57", + "duration": 4784000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T19:52:41", + "duration": 7639000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T08:30:00", + "duration": 993000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T08:46:33", + "duration": 11607000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T03:30:00", + "duration": 14251000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T07:27:31", + "duration": 3604000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T08:27:35", + "duration": 145000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T12:00:00", + "duration": 1528000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T12:25:28", + "duration": 5400000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T13:55:27", + "duration": 14673000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:00:00", + "duration": 887000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:14:47", + "duration": 60000, + "percent": 0.6, + "rate": 0.99, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:15:04", + "duration": 23000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:15:27", + "duration": 3147000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T01:07:54", + "duration": 435000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T04:15:09", + "duration": 14000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T04:15:23", + "duration": 9240000, + "percent": 0.65, + "rate": 1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T06:46:52", + "duration": 297000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T06:51:49", + "duration": 17000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T06:52:06", + "duration": 3600000, + "percent": 0.85, + "rate": 1.31, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T07:52:06", + "duration": 2274000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T18:00:00", + "duration": 10401000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T20:53:21", + "duration": 16200000, + "percent": 1.65, + "rate": 1.89, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T22:00:00", + "duration": 16200000, + "percent": 1.65, + "rate": 2.39, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T00:00:00", + "duration": 16200000, + "percent": 1.65, + "rate": 2.72, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T01:23:21", + "duration": 566000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T01:32:47", + "duration": 12600000, + "percent": 1.65, + "rate": 2.72, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T03:30:00", + "duration": 12600000, + "percent": 1.65, + "rate": 2.55, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T05:02:47", + "duration": 12433000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T12:00:00", + "duration": 18910000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T17:15:10", + "duration": 10800000, + "percent": 1.45, + "rate": 0.94, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T18:00:00", + "duration": 10800000, + "percent": 1.45, + "rate": 1.66, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.14, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T20:15:10", + "duration": 6290000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T12:00:00", + "duration": 8739000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T14:25:39", + "duration": 1563000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T14:51:42", + "duration": 5877000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T16:29:39", + "duration": 10800000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T18:00:00", + "duration": 10800000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T19:29:39", + "duration": 9021000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T18:00:00", + "duration": 813000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T18:13:33", + "duration": 18000000, + "percent": 1.65, + "rate": 1.89, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T22:00:00", + "duration": 18000000, + "percent": 1.65, + "rate": 2.39, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T23:13:33", + "duration": 2787000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T12:00:00", + "duration": 12800000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T15:33:20", + "duration": 256000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T15:37:36", + "duration": 8544000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T00:00:00", + "duration": 586000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T00:09:46", + "duration": 12600000, + "percent": 1.7, + "rate": 2.8, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T03:30:00", + "duration": 12600000, + "percent": 1.7, + "rate": 2.63, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T03:39:46", + "duration": 17414000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T12:00:00", + "duration": 17302000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T16:48:22", + "duration": 7200000, + "percent": 1.6, + "rate": 1.04, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T18:00:00", + "duration": 7200000, + "percent": 1.6, + "rate": 1.84, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T18:48:22", + "duration": 11498000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T12:00:00", + "duration": 19646000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T17:27:26", + "duration": 10800000, + "percent": 1.75, + "rate": 1.13, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T18:00:00", + "duration": 10800000, + "percent": 1.75, + "rate": 2.01, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T20:27:26", + "duration": 5554000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T22:00:00", + "duration": 3002000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T22:50:02", + "duration": 416000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T22:56:58", + "duration": 3782000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T12:00:00", + "duration": 11357000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T15:09:17", + "duration": 12600000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T18:00:00", + "duration": 12600000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T18:39:17", + "duration": 12043000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T08:30:00", + "duration": 9912000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T11:15:12", + "duration": 9000000, + "percent": 0.4, + "rate": 0.58, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T12:00:00", + "duration": 8340000, + "percent": 0.4, + "rate": 0.26, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T13:33:32", + "duration": 38000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T10:34:10", + "duration": 627000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T10:44:37", + "duration": 3600000, + "percent": 1.15, + "rate": 1.66, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T11:44:37", + "duration": 923000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T18:00:00", + "duration": 10191000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T20:49:51", + "duration": 12600000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T22:00:00", + "duration": 12600000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T00:00:00", + "duration": 12600000, + "percent": 1.4, + "rate": 2.31, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T00:19:51", + "duration": 11409000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T03:30:00", + "duration": 2088000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T04:04:48", + "duration": 20248000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T09:42:16", + "duration": 8264000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T12:00:00", + "duration": 7234000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T14:00:34", + "duration": 5400000, + "percent": 1.6, + "rate": 1.04, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T15:30:34", + "duration": 8966000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T03:30:00", + "duration": 16729000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:08:49", + "duration": 7200000, + "percent": 1.5, + "rate": 2.32, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:30:00", + "duration": 7200000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T10:08:49", + "duration": 6671000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T12:00:00", + "duration": 65000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T12:01:05", + "duration": 421000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T12:08:06", + "duration": 21114000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T18:00:00", + "duration": 4889000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T19:21:29", + "duration": 14570000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T23:24:19", + "duration": 2141000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T03:30:00", + "duration": 13402000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T07:13:22", + "duration": 17773000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T12:09:35", + "duration": 5452000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T13:40:27", + "duration": 9000000, + "percent": 1.5, + "rate": 0.97, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T16:10:27", + "duration": 6573000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T03:30:00", + "duration": 6646000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T05:20:46", + "duration": 81000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T04:22:07", + "duration": 14873000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T18:00:00", + "duration": 3581000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "annotations": [{ "code": "basal/unknown-duration" }], + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T18:59:41", + "duration": 0 + } +] +` + +func GetPlatformBasalData() []map[string]interface{} { + data := []map[string]interface{}{} + json.Unmarshal([]byte(platformBasalStr), &data) + return data +} From 6d0cd04a0fda025f057ab314f8d302aac4164eab Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 30 Jul 2024 10:51:05 +1200 Subject: [PATCH 364/413] combine all verification code and scripts --- .../verify/cleanup_user_data.sh | 28 + .../verify/data_verify.go | 320 + .../verify/data_verify_test.go | 137 + .../{ => verify}/fetch_blobs.sh | 16 +- .../verify/process_all_blobs.sh | 13 + .../verify/test/data_verify.go | 81405 ++++++++++++++++ .../verify/upload_blob.sh | 55 + .../verify/utils_suite_test.go | 11 + .../verify/verify.go | 9 +- 9 files changed, 81987 insertions(+), 7 deletions(-) create mode 100644 migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh create mode 100644 migrations/20231128_jellyfish_migration/verify/data_verify.go create mode 100644 migrations/20231128_jellyfish_migration/verify/data_verify_test.go rename migrations/20231128_jellyfish_migration/{ => verify}/fetch_blobs.sh (69%) create mode 100644 migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh create mode 100644 migrations/20231128_jellyfish_migration/verify/test/data_verify.go create mode 100644 migrations/20231128_jellyfish_migration/verify/upload_blob.sh create mode 100644 migrations/20231128_jellyfish_migration/verify/utils_suite_test.go diff --git a/migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh b/migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh new file mode 100644 index 0000000000..0f66d4d49e --- /dev/null +++ b/migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh @@ -0,0 +1,28 @@ +#!/bin/bash +API_ENV=qa3.development +USER_ID_ONE=$1 +SERVER_TOKEN=$2 + +check_val() { + if [[ -z "$1" ]]; then + echo "missing $2 value" + exit 2 + fi +} + +check_val $SERVER_SECRET "SERVER_SECRET" +check_val $USER_ID_ONE "USER_ID_ONE" + +if [[ -z "$SERVER_TOKEN" ]]; then + + SERVER_TOKEN="$(curl -s -I -X POST -H "X-Tidepool-Server-Secret: $SERVER_SECRET" -H "X-Tidepool-Server-Name: devops" "https://${API_ENV}.tidepool.org/auth/serverlogin" | grep 'x-tidepool-session-token' | sed 's/[^:]*: //')" +fi + +check_val $SERVER_TOKEN "SERVER_TOKEN" + +http_response=$(curl -s -w "%{response_code}" --request DELETE \ + --url https://${API_ENV}.tidepool.org/v1/users/${USER_ID_ONE}/data \ + --header 'Accept: */*' \ + --header "X-Tidepool-Session-Token: $SERVER_TOKEN") + +echo "status $http_response deleting data for user $USER_ID_ONE" diff --git a/migrations/20231128_jellyfish_migration/verify/data_verify.go b/migrations/20231128_jellyfish_migration/verify/data_verify.go new file mode 100644 index 0000000000..3b6d5968d7 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/verify/data_verify.go @@ -0,0 +1,320 @@ +package main + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "log" + "os" + "path/filepath" + + "github.com/r3labs/diff/v3" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + +type DataVerify struct { + ctx context.Context + dataC *mongo.Collection +} + +func CompareDatasetDatums(platformData []map[string]interface{}, jellyfishData []map[string]interface{}, ignoredPaths ...string) (map[string]interface{}, error) { + diffs := map[string]interface{}{} + for id, platformDatum := range platformData { + if jellyfishData[id] == nil { + log.Println("no matching value in the jellyfish data") + break + } + changelog, err := diff.Diff(platformDatum, jellyfishData[id], diff.ConvertCompatibleTypes(), diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) + if err != nil { + return nil, err + } + if len(changelog) > 0 { + if ignoredPaths != nil { + for _, path := range ignoredPaths { + changelog = changelog.FilterOut([]string{path}) + } + if len(changelog) == 0 { + continue + } + } + diffs[fmt.Sprintf("platform_%d", id)] = changelog + } + } + return diffs, nil +} + +func NewDataVerify(ctx context.Context, dataC *mongo.Collection) (*DataVerify, error) { + + if dataC == nil { + return nil, errors.New("missing required data collection") + } + + m := &DataVerify{ + ctx: ctx, + dataC: dataC, + } + + return m, nil +} + +var DatasetTypes = []string{"cbg", "smbg", "basal", "bolus", "deviceEvent", "wizard", "pumpSettings"} + +func (m *DataVerify) fetchDataSet(uploadID string, dataTypes []string) (map[string][]map[string]interface{}, error) { + if m.dataC == nil { + return nil, errors.New("missing data collection") + } + + typeSet := map[string][]map[string]interface{}{} + + for _, dType := range dataTypes { + + dset := []map[string]interface{}{} + + filter := bson.M{ + "uploadId": uploadID, + "type": dType, + } + + sort := bson.D{{Key: "time", Value: 1}} + + if dType == "deviceEvent" || dType == "bolus" { + sort = bson.D{{Key: "time", Value: 1}, {Key: "subType", Value: 1}} + } + + excludedFeilds := bson.M{ + "_active": 0, + "_archivedTime": 0, + "createdTime": 0, + "clockDriftOffset": 0, + "conversionOffset": 0, + "deduplicator": 0, + "_deduplicator": 0, + "_groupId": 0, + "guid": 0, + "_id": 0, + "id": 0, + "modifiedTime": 0, + "payload": 0, + "provenance": 0, + "revision": 0, + "_schemaVersion": 0, + "time": 0, + "timezoneOffset": 0, + "type": 0, + "_userId": 0, + "uploadId": 0, + "_version": 0, + } + + dDataCursor, err := m.dataC.Find(m.ctx, filter, &options.FindOptions{ + Sort: sort, + Projection: excludedFeilds, + }) + if err != nil { + return nil, err + } + defer dDataCursor.Close(m.ctx) + + if err := dDataCursor.All(m.ctx, &dset); err != nil { + return nil, err + } + log.Printf("got dataset [%s][%s][%d] results", uploadID, dType, len(dset)) + typeSet[dType] = dset + } + return typeSet, nil +} + +func (m *DataVerify) WriteBlobIDs() error { + if m.dataC == nil { + return errors.New("missing data collection") + } + + blobData := []map[string]interface{}{} + + dDataCursor, err := m.dataC.Find(m.ctx, bson.M{ + "deviceManufacturers": bson.M{"$in": []string{"Tandem", "Insulet"}}, + "client.private.blobId": bson.M{"$exists": true}, + "_active": true, + }, &options.FindOptions{ + Sort: bson.D{{Key: "deviceId", Value: 1}, {Key: "time", Value: 1}}, + Projection: bson.M{"_id": 0, "deviceId": 1, "blobId": "$client.private.blobId", "time": 1}, + }) + if err != nil { + return err + } + defer dDataCursor.Close(m.ctx) + + if err := dDataCursor.All(m.ctx, &blobData); err != nil { + return err + } + + type Blob struct { + DeviceID string `json:"deviceId"` + BlobID string `json:"blobId"` + } + + blobs := []Blob{} + + for _, v := range blobData { + blobs = append(blobs, Blob{ + BlobID: fmt.Sprintf("%v", v["blobId"]), + DeviceID: fmt.Sprintf("%v", v["deviceId"])}) + } + + blobPath := filepath.Join(".", "_blobs") + log.Printf("blob data written to %s", blobPath) + writeFileData(blobs, blobPath, "device_blobs.json", true) + return nil +} + +const ( + PlatformExtra = "extra" + PlatformDuplicate = "duplicate" + PlatformMissing = "missing" +) + +func CompareDatasets(platformSet []map[string]interface{}, jellyfishSet []map[string]interface{}) map[string][]map[string]interface{} { + + diffs := map[string][]map[string]interface{}{ + PlatformExtra: {}, + PlatformDuplicate: {}, + PlatformMissing: {}, + } + const deviceTimeName = "deviceTime" + type deviceTimeDatums map[string][]map[string]interface{} + + pfCounts := deviceTimeDatums{} + jfCounts := deviceTimeDatums{} + + for _, jDatum := range jellyfishSet { + strDatumTime := fmt.Sprintf("%v", jDatum[deviceTimeName]) + + if len(jfCounts[strDatumTime]) == 0 { + jfCounts[strDatumTime] = []map[string]interface{}{jDatum} + } else if len(jfCounts[strDatumTime]) >= 1 { + jfCounts[strDatumTime] = append(jfCounts[strDatumTime], jDatum) + } + } + + for _, pDatum := range platformSet { + + strDatumTime := fmt.Sprintf("%v", pDatum[deviceTimeName]) + + if len(pfCounts[strDatumTime]) == 0 { + pfCounts[strDatumTime] = []map[string]interface{}{pDatum} + } else if len(pfCounts[strDatumTime]) >= 1 { + + currentItems := pfCounts[strDatumTime] + for _, item := range currentItems { + if fmt.Sprintf("%v", item) == fmt.Sprintf("%v", pDatum) { + diffs[PlatformDuplicate] = append(diffs[PlatformDuplicate], pDatum) + continue + } else { + diffs[PlatformExtra] = append(diffs[PlatformExtra], pDatum) + break + } + } + pfCounts[strDatumTime] = append(pfCounts[strDatumTime], pDatum) + } + if len(jfCounts[fmt.Sprintf("%v", pDatum[deviceTimeName])]) == 0 { + diffs[PlatformExtra] = append(diffs[PlatformExtra], pDatum) + } + } + + for jfDeviceTimeStr, jDatums := range jfCounts { + if len(pfCounts[jfDeviceTimeStr]) < len(jfCounts[jfDeviceTimeStr]) { + //NOTE: more of an indicator there are missing records ... + for i := len(pfCounts[jfDeviceTimeStr]); i < len(jfCounts[jfDeviceTimeStr]); i++ { + diffs[PlatformMissing] = append(diffs[PlatformMissing], jDatums[i]) + } + } + } + return diffs +} + +var dataTypePathIgnored = map[string][]string{ + "smbg": {"raw", "value"}, + "cbg": {"value"}, + "basal": {"rate"}, + "bolus": {"normal"}, +} + +func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUploadID string, dataTyes []string) error { + + if len(dataTyes) == 0 { + dataTyes = DatasetTypes + } + + platformDataset, err := m.fetchDataSet(platformUploadID, dataTyes) + if err != nil { + return err + } + + jellyfishDataset, err := m.fetchDataSet(jellyfishUploadID, dataTyes) + if err != nil { + return err + } + + log.Printf("Compare platform[%s] vs jellyfish[%s]", platformUploadID, jellyfishUploadID) + + for dType, jfSet := range jellyfishDataset { + pfSet := platformDataset[dType] + comparePath := filepath.Join(".", "_compare", fmt.Sprintf("%s_%s", platformUploadID, jellyfishUploadID)) + log.Printf("data written to %s", comparePath) + setDifferences := CompareDatasets(pfSet, jfSet) + if len(setDifferences[PlatformMissing]) > 0 { + writeFileData(setDifferences[PlatformMissing], comparePath, fmt.Sprintf("%s_platform_missing.json", dType), true) + } + if len(setDifferences[PlatformDuplicate]) > 0 { + writeFileData(setDifferences[PlatformDuplicate], comparePath, fmt.Sprintf("%s_platform_duplicates.json", dType), true) + } + if len(setDifferences[PlatformExtra]) > 0 { + writeFileData(setDifferences[PlatformExtra], comparePath, fmt.Sprintf("%s_platform_extra.json", dType), true) + } + if len(pfSet) != len(jfSet) { + log.Printf("NOTE: datasets mismatch platform (%d) vs jellyfish (%d)", len(pfSet), len(jfSet)) + writeFileData(jfSet, comparePath, fmt.Sprintf("%s_jellyfish_datums.json", dType), true) + writeFileData(pfSet, comparePath, fmt.Sprintf("%s_platform_datums.json", dType), true) + break + } + differences, err := CompareDatasetDatums(pfSet, jfSet, dataTypePathIgnored[dType]...) + if err != nil { + return err + } + if len(differences) > 0 { + writeFileData(differences, comparePath, fmt.Sprintf("%s_datum_diff.json", dType), true) + } + } + return nil +} + +func writeFileData(data interface{}, path string, name string, asJSON bool) { + if data == nil || path == "" || name == "" { + return + } + + var handleErr = func(err error) { + if err != nil { + log.Println(err) + os.Exit(1) + } + } + + err := os.MkdirAll(path, os.ModePerm) + handleErr(err) + f, err := os.OpenFile(fmt.Sprintf("%s/%s", path, name), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + handleErr(err) + + defer f.Close() + + if asJSON { + jsonData, err := json.Marshal(data) + handleErr(err) + f.WriteString(string(jsonData) + "\n") + return + } + f.WriteString(fmt.Sprintf("%v", data)) +} diff --git a/migrations/20231128_jellyfish_migration/verify/data_verify_test.go b/migrations/20231128_jellyfish_migration/verify/data_verify_test.go new file mode 100644 index 0000000000..c3dc274469 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/verify/data_verify_test.go @@ -0,0 +1,137 @@ +package main_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/r3labs/diff/v3" + + "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/verify/test" + + verify "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/verify" +) + +var _ = Describe("DataVerify", func() { + + var _ = Describe("CompareDatasetDatums", func() { + + var datasetOne = []map[string]interface{}{} + var datasetTwo = []map[string]interface{}{} + + BeforeEach(func() { + + datasetOne = []map[string]interface{}{ + { + "one": 1, + "value": 2, + }, + { + "three": 3, + "more": true, + }, + } + + datasetTwo = []map[string]interface{}{ + { + "one": "one", + "value": 2, + }, + { + "three": 3, + "more": false, + }, + } + + }) + + It("will genterate a list of differences between two datasets", func() { + changes, err := verify.CompareDatasetDatums(datasetOne, datasetTwo) + Expect(err).To(BeNil()) + Expect(changes).ToNot(BeEmpty()) + }) + + It("will genterate no differences when the datasets are the same ", func() { + changes, err := verify.CompareDatasetDatums(datasetOne, datasetOne) + Expect(err).To(BeNil()) + Expect(changes).To(BeEmpty()) + }) + + It("changes will contain each diff", func() { + changes, err := verify.CompareDatasetDatums(datasetOne, datasetTwo) + Expect(err).To(BeNil()) + Expect(changes).To(Equal(map[string]interface{}{ + "platform_0": diff.Changelog{{Type: diff.UPDATE, Path: []string{"one"}, From: 1, To: "one"}}, + "platform_1": diff.Changelog{{Type: diff.UPDATE, Path: []string{"more"}, From: true, To: false}}, + })) + }) + + It("can filter based on path", func() { + changes, err := verify.CompareDatasetDatums(datasetOne, datasetTwo, "more") + Expect(err).To(BeNil()) + Expect(changes).To(Equal(map[string]interface{}{ + "platform_0": diff.Changelog{{Type: diff.UPDATE, Path: []string{"one"}, From: 1, To: "one"}}, + })) + }) + + It("can filter multiple based on path", func() { + changes, err := verify.CompareDatasetDatums(datasetOne, datasetTwo, "more", "one") + Expect(err).To(BeNil()) + Expect(changes).To(BeEmpty()) + }) + + }) + var _ = Describe("CompareDatasets", func() { + + It("will have no differences when that same and no dups", func() { + dSetDifference := verify.CompareDatasets(test.JFBolusSet, test.JFBolusSet) + Expect(len(dSetDifference[verify.PlatformDuplicate])).To(Equal(0)) + Expect(len(dSetDifference[verify.PlatformExtra])).To(Equal(0)) + Expect(len(dSetDifference[verify.PlatformMissing])).To(Equal(0)) + }) + + It("will find duplicates in the platform dataset", func() { + dSetDifference := verify.CompareDatasets(test.PlatformBolusSet, test.JFBolusSet) + Expect(len(dSetDifference[verify.PlatformDuplicate])).To(Equal(395)) + Expect(len(dSetDifference[verify.PlatformExtra])).To(Equal(0)) + Expect(len(dSetDifference[verify.PlatformMissing])).To(Equal(0)) + }) + + It("will find extras in the platform dataset that have duplicate timestamp but not data", func() { + duplicateTimeStamp := map[string]interface{}{ + "extra": true, + "deviceTime": "2018-01-03T13:07:10", + } + + dSetDifference := verify.CompareDatasets(append(test.PlatformBolusSet, duplicateTimeStamp), test.JFBolusSet) + Expect(len(dSetDifference[verify.PlatformDuplicate])).To(Equal(395)) + Expect(len(dSetDifference[verify.PlatformExtra])).To(Equal(1)) + Expect(len(dSetDifference[verify.PlatformMissing])).To(Equal(0)) + }) + + It("will find extras in the platform dataset", func() { + expectedExtra := map[string]interface{}{ + "extra": 3, + "deviceTime": "2023-01-18T12:00:00", + } + + dSetDifference := verify.CompareDatasets(append(test.PlatformBolusSet, expectedExtra), test.JFBolusSet) + Expect(len(dSetDifference[verify.PlatformDuplicate])).To(Equal(395)) + Expect(len(dSetDifference[verify.PlatformExtra])).To(Equal(1)) + Expect(dSetDifference[verify.PlatformExtra][0]).To(Equal(expectedExtra)) + Expect(len(dSetDifference[verify.PlatformMissing])).To(Equal(0)) + }) + + It("will find datums that are missing in the platform dataset", func() { + platformBasals := test.GetPlatformBasalData() + jellyfishBasals := test.GetJFBasalData() + + Expect(len(platformBasals)).To(Equal(3123)) + Expect(len(jellyfishBasals)).To(Equal(3386)) + + dSetDifference := verify.CompareDatasets(platformBasals, jellyfishBasals) + Expect(len(dSetDifference[verify.PlatformDuplicate])).To(Equal(5)) + Expect(len(dSetDifference[verify.PlatformExtra])).To(Equal(4)) + Expect(len(dSetDifference[verify.PlatformMissing])).To(Equal(263)) + }) + + }) +}) diff --git a/migrations/20231128_jellyfish_migration/fetch_blobs.sh b/migrations/20231128_jellyfish_migration/verify/fetch_blobs.sh similarity index 69% rename from migrations/20231128_jellyfish_migration/fetch_blobs.sh rename to migrations/20231128_jellyfish_migration/verify/fetch_blobs.sh index 2f8a7693fb..3a613cc733 100644 --- a/migrations/20231128_jellyfish_migration/fetch_blobs.sh +++ b/migrations/20231128_jellyfish_migration/verify/fetch_blobs.sh @@ -24,7 +24,14 @@ jq -c '.[]' $JSON_FILE | while read i; do BLOB_ID=$(jq -r '.blobId' <<<"$i") check_val $BLOB_ID "BLOB_ID" - OUTPUT_FILE="$OUTPUT_DIR/$DEVICE_ID"_blob.gz + + if [[ "$DEVICE_ID" =~ .*"tandem".* ]]; then + OUTPUT_FILE="$OUTPUT_DIR/$DEVICE_ID/$BLOB_ID"_blob.gz + else + OUTPUT_FILE="$OUTPUT_DIR/$DEVICE_ID/$BLOB_ID"_blob.ibf + fi + + mkdir -p "$OUTPUT_DIR/$DEVICE_ID" check_val $OUTPUT_FILE "OUTPUT_FILE" @@ -37,7 +44,12 @@ jq -c '.[]' $JSON_FILE | while read i; do echo "$http_response error downloading blob $BLOB_ID for device $DEVICE_ID" rm -rf $OUTPUT_FILE else - echo "status $http_response done downloading blob $BLOB_ID" + if [[ "$DEVICE_ID" =~ .*"tandem".* ]]; then + echo "status $http_response done downloading tandem blob $OUTPUT_FILE" + else + gzip $OUTPUT_FILE + echo "status $http_response done downloading omnipod blob $OUTPUT_FILE" + fi fi done diff --git a/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh b/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh new file mode 100644 index 0000000000..9c5428d5da --- /dev/null +++ b/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh @@ -0,0 +1,13 @@ +#!/bin/bash +BLOBS_DIR=~/Documents/tmp/blob_files/tandemCIQ100035490810069 +USER_ID=6a452338-5064-4795-81ca-84957bad2280 +USER_EMAIL=$1 +USER_PW=$2 + +SERVER_TOKEN="$(curl -s -I -X POST -H "X-Tidepool-Server-Secret: $SERVER_SECRET" -H "X-Tidepool-Server-Name: devops" "https://${API_ENV}.tidepool.org/auth/serverlogin" | grep 'x-tidepool-session-token' | sed 's/[^:]*: //')" + +for filename in $BLOBS_DIR/**/*blob.gz; do + echo "$filename" + source ./upload_blob.sh "$filename" "$USER_EMAIL" "$USER_PW" + source ./cleanup_user_data.sh "$USER_ID" "$SERVER_TOKEN" +done diff --git a/migrations/20231128_jellyfish_migration/verify/test/data_verify.go b/migrations/20231128_jellyfish_migration/verify/test/data_verify.go new file mode 100644 index 0000000000..a089143b96 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/verify/test/data_verify.go @@ -0,0 +1,81405 @@ +package test + +import "encoding/json" + +var JFBolusSet = []map[string]interface{}{ + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-11T05:48:32", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-11T08:48:43", + "normal": 2.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-11T17:07:35", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-11T17:48:17", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-11T22:16:32", + "expectedNormal": 6, + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T02:48:01", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T02:57:56", + "normal": 2.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T03:45:23", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T04:02:33", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T04:07:54", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T12:10:52", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T13:43:31", + "normal": 0.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T18:55:53", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T22:06:00", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-13T00:07:54", + "normal": 6.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-13T15:36:15", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-13T19:15:32", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-13T23:32:46", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-14T02:56:18", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-14T15:05:16", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-14T18:45:59", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-14T21:06:30", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-15T02:10:44", + "expectedNormal": 6, + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-15T10:11:52", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-15T10:21:08", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-15T10:52:13", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-15T18:51:32", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-15T20:32:07", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-15T20:43:33", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-15T21:26:55", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-16T07:56:57", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-16T15:32:09", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-16T16:04:19", + "expectedNormal": 3.7, + "normal": 0.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-16T16:04:45", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-16T16:23:41", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-16T16:35:34", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-16T16:58:46", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-16T22:04:48", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T07:49:22", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T07:58:22", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T08:31:44", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T09:25:59", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T15:19:35", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T15:41:16", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T16:13:32", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T16:51:39", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T17:36:34", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T22:24:30", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-18T00:26:16", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-18T00:57:05", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-18T09:39:10", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-18T13:26:16", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-18T15:56:31", + "normal": 0.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-18T16:46:24", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-18T17:16:59", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-19T01:21:09", + "normal": 2.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-19T01:51:44", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-19T18:01:16", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-19T19:01:35", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-19T22:24:42", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-19T22:27:54", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-19T23:16:39", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-20T11:50:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-20T13:36:40", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-20T18:31:12", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-20T19:04:49", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-20T19:13:53", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-21T14:16:39", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-22T00:12:03", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-22T13:54:39", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-22T20:02:33", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-22T20:09:02", + "normal": 7.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-22T20:42:46", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-22T20:51:20", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-23T14:51:38", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-23T17:40:56", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-24T10:57:40", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-24T13:49:15", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-24T20:29:08", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-24T23:20:14", + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T02:11:25", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T03:41:15", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T03:49:26", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T11:34:54", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T11:36:30", + "expectedNormal": 3.7, + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T11:39:54", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T18:55:44", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T21:00:32", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T21:56:23", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T22:40:16", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-26T00:47:19", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-26T11:19:24", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-26T18:22:46", + "normal": 9.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-26T20:06:31", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-26T21:00:39", + "normal": 4.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-27T00:43:11", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-27T00:54:23", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-27T01:21:34", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-27T07:02:47", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-27T08:20:19", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-27T11:57:25", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-27T18:36:04", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-27T20:18:11", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-28T10:55:51", + "normal": 10.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-28T13:31:27", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-28T17:47:15", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-28T18:58:25", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-28T20:20:09", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T05:47:36", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T11:04:51", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T11:17:10", + "expectedNormal": 5, + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T11:17:44", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T11:59:21", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T12:33:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T16:04:51", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T18:22:02", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T20:35:15", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-30T00:19:10", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-30T01:14:53", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-30T11:38:04", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-30T14:10:30", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-30T18:11:40", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-30T19:40:37", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-30T22:39:58", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-01T09:55:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-01T12:02:23", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-01T12:11:07", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-01T15:03:11", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-01T23:36:08", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-02T13:42:27", + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-03T08:36:32", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-03T12:46:16", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-03T14:31:00", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-03T19:01:03", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-03T19:13:12", + "duration": 3600000, + "extended": 1.35, + "normal": 3.25, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-03T23:09:17", + "expectedNormal": 5.6, + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-04T01:32:34", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-04T13:31:48", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-04T23:45:20", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-05T05:38:22", + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-05T13:05:36", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-05T18:04:44", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-05T22:31:49", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-06T09:05:49", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-06T19:44:34", + "normal": 3.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-07T11:30:47", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-07T17:39:58", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-08T09:36:46", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-08T12:09:06", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-08T13:51:33", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-08T22:47:22", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-08T23:06:37", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-08T23:34:05", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-09T11:51:03", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-09T18:28:48", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-09T18:41:43", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-09T19:46:42", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-09T22:41:34", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-10T03:05:28", + "normal": 1.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-10T11:34:38", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-10T14:55:50", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-10T15:23:08", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-10T19:28:56", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-10T21:16:11", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-10T22:17:25", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-11T14:30:42", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-11T19:17:18", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-12T13:15:43", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-12T14:37:19", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-12T20:45:23", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-12T21:17:50", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-12T22:07:50", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-12T23:57:33", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-13T10:28:04", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-13T17:42:12", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-14T04:31:16", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-14T09:40:01", + "normal": 3.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-14T15:57:40", + "normal": 2.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-14T17:26:58", + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-15T05:49:43", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-15T09:42:54", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-15T15:42:11", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-15T17:58:05", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-15T20:36:40", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-15T21:54:57", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-16T02:10:54", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-16T05:18:35", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-16T17:03:43", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-16T21:17:40", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-16T21:27:12", + "expectedNormal": 1.8, + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-17T15:02:37", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-18T08:53:51", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-18T14:07:21", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-19T00:37:12", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-20T22:52:22", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-21T16:04:44", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-21T17:31:36", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-22T20:34:13", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T00:32:29", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T02:01:53", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T13:25:12", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T14:45:29", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T15:17:41", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T15:27:27", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T20:51:42", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T22:28:05", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-24T15:45:49", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-24T17:30:54", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-25T03:24:31", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-25T17:51:24", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-25T18:17:02", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-25T18:44:42", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-25T19:06:09", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-26T04:38:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-26T21:52:20", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-26T22:10:35", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-27T00:35:55", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-27T12:09:08", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-27T13:12:31", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-27T22:06:04", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-27T23:57:59", + "normal": 8.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-28T13:41:05", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-28T21:53:48", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-28T22:38:58", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-28T23:35:34", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-29T01:10:10", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-29T13:28:49", + "normal": 7.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-29T15:31:09", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-29T15:47:25", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-29T20:49:26", + "normal": 10.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-29T23:31:22", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T01:14:51", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T10:07:54", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T14:41:41", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T15:36:28", + "normal": 0.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T17:21:07", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T17:47:07", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T19:43:22", + "normal": 10.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T21:42:19", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T23:34:45", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T23:57:13", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-31T14:15:24", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-31T15:37:20", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-31T16:37:23", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-31T20:22:35", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-31T22:50:28", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-01T00:18:37", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-01T03:28:56", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-01T08:23:20", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-01T17:09:58", + "normal": 5.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-01T20:29:55", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-01T21:39:29", + "normal": 11.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T01:37:45", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T09:05:27", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T09:28:02", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T15:17:44", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T17:05:07", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T21:57:29", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T22:31:41", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T23:58:14", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-03T06:23:16", + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-03T13:07:10", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-03T17:36:24", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-03T19:19:53", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-04T20:39:32", + "normal": 12.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-04T23:27:30", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-05T11:26:40", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-05T14:39:47", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-05T21:24:08", + "normal": 12.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-05T23:47:57", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-06T10:29:13", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-07T02:43:11", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-07T15:29:23", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-07T15:53:38", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-08T00:50:58", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-08T02:22:40", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-08T10:49:22", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-08T12:10:15", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-08T16:06:15", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-08T21:00:55", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-08T22:52:11", + "normal": 13.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-09T06:48:05", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-09T11:57:20", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-09T14:50:09", + "expectedNormal": 7.1, + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-09T15:09:57", + "expectedNormal": 5.3, + "normal": 0, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-09T15:10:07", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-09T15:45:24", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-09T19:08:06", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-10T00:20:48", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-10T09:57:07", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-10T15:19:38", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-10T19:51:35", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-10T21:04:03", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-11T17:21:27", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-11T23:50:01", + "normal": 9.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-12T14:21:27", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-13T01:22:50", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-13T09:16:42", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-13T09:45:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-13T17:59:12", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-13T19:51:42", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-14T01:09:36", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-14T15:27:34", + "normal": 6.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-14T15:37:30", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-14T19:52:15", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-14T22:44:38", + "normal": 11, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-14T23:04:59", + "expectedNormal": 8.7, + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-15T08:08:01", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-15T17:50:26", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-15T18:22:34", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-15T22:12:43", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-16T05:28:57", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-16T19:06:03", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-18T00:44:27", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-18T15:16:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-18T21:34:19", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-19T15:18:48", + "normal": 7.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-19T18:24:25", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-19T21:40:18", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-20T01:57:09", + "normal": 5.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-20T05:21:15", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-20T14:43:26", + "normal": 2.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-20T20:23:29", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-20T23:15:21", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-21T01:47:25", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-21T16:32:58", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-21T21:12:41", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-22T13:07:23", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-22T13:24:37", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-22T13:38:43", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-22T14:23:46", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-23T00:01:17", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-23T02:53:10", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-23T10:26:09", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-23T12:45:53", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-23T19:04:33", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-24T02:03:30", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-24T08:42:05", + "normal": 3.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-24T09:11:28", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-24T13:05:25", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-24T16:20:41", + "normal": 0.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-24T19:39:24", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-24T22:58:57", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-25T09:05:32", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-25T09:15:49", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-25T10:05:32", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-25T15:20:46", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-26T00:34:00", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-26T00:40:32", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-26T17:42:21", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-27T00:26:46", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-27T01:56:53", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-27T15:00:57", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-27T16:30:36", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-28T00:07:24", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-28T04:04:35", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-28T11:06:58", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-28T12:05:56", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-28T17:32:14", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-28T22:51:31", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-29T09:24:11", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-29T11:48:49", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-31T17:35:53", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-01T22:39:45", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-01T23:11:22", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-02T05:32:22", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-02T13:53:59", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-02T15:01:02", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-03T11:47:19", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-03T17:52:13", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-04T00:51:30", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-04T01:35:03", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-04T10:23:28", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-05T00:40:31", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-05T22:10:18", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-06T00:30:31", + "duration": 9000000, + "extended": 2.4, + "normal": 0.1, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-06T11:27:46", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-06T12:24:47", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-06T21:00:06", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-06T21:26:09", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-06T22:30:08", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-07T01:20:24", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-07T15:08:42", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-07T17:35:21", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-08T00:40:52", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-08T04:05:56", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-08T04:08:07", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-08T20:24:34", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-08T21:17:19", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-09T03:41:21", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-09T03:43:00", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-09T15:27:27", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-09T16:50:23", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-10T00:06:05", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-10T07:13:02", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-10T10:23:08", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-11T01:16:30", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-11T13:20:10", + "normal": 1.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-11T17:04:18", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-11T19:38:24", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-11T20:40:19", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-11T22:22:57", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-11T23:03:25", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-12T10:31:15", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-12T10:47:00", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-12T17:15:24", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-12T22:52:54", + "duration": 5400000, + "extended": 3.6, + "normal": 0.4, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-12T23:37:16", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-13T03:06:20", + "expectedNormal": 2.4, + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-13T04:51:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-13T19:40:33", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-13T20:05:03", + "normal": 0.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-14T17:20:11", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-14T17:56:34", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-15T01:56:38", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-15T17:29:22", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-16T09:23:19", + "normal": 2.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-17T11:56:27", + "normal": 0.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-18T00:34:51", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-18T04:32:23", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-18T12:15:36", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-18T12:56:37", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-18T20:43:52", + "normal": 9.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-19T03:06:10", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-19T17:37:52", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-19T18:33:24", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-19T22:24:06", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-19T23:15:16", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-19T23:57:50", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-20T11:27:44", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-20T12:13:32", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-20T17:12:58", + "normal": 7.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-20T23:25:38", + "normal": 4.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-21T18:12:48", + "normal": 4.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-21T23:02:43", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-22T05:11:08", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-22T12:46:46", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-22T18:44:55", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-22T23:47:30", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-23T15:22:30", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-24T01:28:13", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-24T04:50:59", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-24T10:06:16", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-24T10:57:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-24T16:20:38", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-24T20:57:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-24T21:10:06", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-25T01:46:05", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-25T03:01:41", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-25T12:45:34", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-25T16:35:50", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-25T16:43:09", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-26T14:50:38", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-26T23:18:20", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-27T19:10:37", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-27T19:56:05", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-27T20:05:22", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-27T20:33:26", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-01T11:06:45", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-01T13:38:00", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-01T17:26:06", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-02T05:10:59", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-02T14:53:50", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-02T15:15:41", + "duration": 7200000, + "extended": 4, + "normal": 2.65, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-02T17:55:24", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-02T21:27:07", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-03T02:23:28", + "normal": 3.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-03T07:55:24", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-03T13:31:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-03T17:33:40", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-04T01:00:34", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-04T09:51:54", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-04T13:59:53", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-04T14:53:15", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-04T17:26:51", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-04T19:38:13", + "normal": 8.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-04T23:09:52", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-04T23:57:26", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-05T03:09:50", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-05T14:54:46", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-05T18:29:31", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-06T00:34:35", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-06T01:21:36", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-06T06:12:45", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-06T19:38:19", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-07T08:26:18", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-07T10:24:27", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-07T16:59:43", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-07T22:10:21", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-07T23:47:40", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-08T00:47:32", + "duration": 10800000, + "extended": 1.65, + "subType": "square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-08T17:20:24", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-08T23:16:45", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-09T09:43:12", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-09T19:36:18", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-09T21:47:07", + "normal": 11, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-09T22:28:29", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-10T00:56:27", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-10T05:18:33", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-10T10:09:03", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-10T19:08:41", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-10T19:30:42", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-10T21:00:08", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-10T21:11:26", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-11T00:12:25", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-11T03:50:32", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-11T09:48:55", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-11T17:56:25", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-11T21:45:42", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-11T23:48:21", + "normal": 7.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-11T23:59:24", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-12T11:02:19", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-12T14:13:44", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-12T23:30:03", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-13T00:01:21", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-13T08:23:02", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-13T15:29:58", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-13T16:25:10", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-14T01:00:14", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-14T01:48:33", + "duration": 7200000, + "extended": 5, + "subType": "square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-14T08:26:33", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-14T09:15:40", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-14T21:17:36", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-14T21:36:42", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-15T01:00:44", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-15T12:10:00", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-15T13:36:53", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-15T21:24:43", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-15T22:46:02", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-16T19:49:33", + "normal": 12.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-17T15:56:01", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-18T10:02:04", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-18T15:29:15", + "normal": 6.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-18T16:27:25", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-18T21:15:02", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-19T06:28:44", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-19T15:28:25", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-19T22:15:08", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-20T08:14:49", + "duration": 3600000, + "extended": 1.5, + "normal": 0.5, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-20T12:02:19", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-20T13:19:06", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-20T16:07:19", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-20T19:43:27", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-20T20:56:53", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-21T00:32:48", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-21T14:39:05", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-21T21:09:21", + "normal": 12, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-21T22:14:04", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-22T03:19:52", + "expectedNormal": 5.15, + "normal": 0.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-22T03:20:35", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-22T10:57:48", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-22T16:15:49", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-22T23:32:14", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-23T03:44:48", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-23T10:03:49", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-23T12:03:21", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-23T12:08:31", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-23T17:28:19", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-23T18:10:06", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-23T22:45:10", + "normal": 6.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-23T23:57:11", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-24T01:52:51", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-24T04:04:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-24T10:09:10", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-24T15:22:15", + "normal": 9.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-24T15:59:21", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-24T18:45:12", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-25T03:44:15", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-25T04:12:56", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-25T13:25:50", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-25T15:47:08", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-25T16:27:53", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-25T17:26:51", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-26T01:03:51", + "normal": 9.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-26T04:48:39", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-26T15:52:08", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-26T18:11:28", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-26T21:42:00", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-26T23:21:43", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-27T13:11:38", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-27T13:27:58", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-27T13:43:12", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-27T14:19:41", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-28T01:21:26", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-28T02:49:55", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-28T12:09:39", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-28T21:12:56", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-29T01:42:57", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-29T12:10:07", + "normal": 8.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-29T20:29:43", + "normal": 8.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-29T23:08:20", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-29T23:23:56", + "expectedNormal": 2, + "normal": 0.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-29T23:24:13", + "expectedNormal": 3.8, + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-29T23:25:03", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-30T09:17:33", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-30T11:41:40", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-30T18:46:16", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-30T22:26:35", + "normal": 7.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-31T09:34:04", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-31T11:02:09", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-31T18:03:31", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-01T13:35:12", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-01T19:00:43", + "expectedNormal": 5.5, + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-02T11:24:01", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-03T00:24:02", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-03T04:46:03", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-03T13:58:14", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-03T15:41:52", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-03T22:48:16", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-03T22:53:19", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-03T23:37:06", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-04T17:49:44", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-04T18:25:58", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-04T20:06:51", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-04T20:50:31", + "expectedNormal": 6.5, + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-04T21:47:42", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-05T11:10:22", + "normal": 8.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-05T13:57:52", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-05T14:41:02", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-05T19:55:35", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-05T20:07:23", + "normal": 6.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-05T23:10:52", + "normal": 10.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-06T17:04:13", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-07T00:30:35", + "normal": 13, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-07T11:30:23", + "expectedNormal": 11.3, + "normal": 7.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-07T13:39:36", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-07T15:31:20", + "normal": 7.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-07T17:03:27", + "normal": 6.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-07T19:36:38", + "normal": 11.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T02:04:38", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T11:36:22", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T15:35:43", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T16:36:54", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T17:06:19", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T18:36:43", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T20:45:53", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T21:43:56", + "normal": 5.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T22:27:26", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-09T13:34:32", + "normal": 4.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-09T23:51:42", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-10T11:33:52", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-10T15:06:31", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-10T16:39:01", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-10T23:28:10", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-10T23:56:06", + "normal": 3.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-11T08:31:34", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-11T14:14:04", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-11T21:33:10", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-12T13:11:06", + "normal": 5.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-12T15:22:32", + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-12T20:37:48", + "duration": 3600000, + "extended": 1.4, + "normal": 4.1, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-13T07:00:52", + "normal": 2.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-13T11:55:34", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-13T15:38:33", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-13T16:43:21", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-13T22:25:40", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-13T23:43:31", + "duration": 3600000, + "extended": 3, + "normal": 4.5, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-14T07:24:30", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-14T11:26:07", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-14T14:02:33", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-14T16:13:29", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-14T16:21:37", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-15T04:30:42", + "normal": 2.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-15T11:27:28", + "normal": 9.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-15T21:09:40", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-15T21:29:47", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-16T08:42:28", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-16T09:08:02", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-16T18:50:11", + "normal": 7.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-16T22:19:29", + "normal": 8.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-17T07:49:58", + "expectedNormal": 6.25, + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-17T10:22:10", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-17T15:38:57", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-17T16:53:15", + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-17T23:01:44", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-17T23:17:46", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-18T03:36:54", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-18T08:15:40", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-18T13:03:08", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-18T22:49:11", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-19T10:49:57", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-19T12:47:07", + "normal": 7.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-19T18:51:49", + "normal": 0.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T00:34:12", + "normal": 4.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T11:55:56", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T12:21:25", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T12:25:59", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T12:40:44", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T16:51:52", + "normal": 5.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T17:13:53", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T18:53:57", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T21:13:02", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T21:17:28", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T22:56:20", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-21T05:00:30", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-21T14:57:12", + "expectedNormal": 5.7, + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-21T17:25:57", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-21T19:55:14", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-21T20:21:02", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-21T20:48:12", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-21T23:36:01", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-22T00:17:02", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-22T07:20:00", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-22T09:32:51", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-22T15:34:54", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-22T17:17:07", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-22T18:33:33", + "normal": 8.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-22T19:56:36", + "normal": 4.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-22T21:38:22", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-23T14:44:27", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-23T16:39:55", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-23T17:17:36", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-23T18:45:04", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-23T21:54:57", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-23T23:08:34", + "expectedNormal": 2.5, + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-23T23:30:54", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-24T10:55:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-24T16:10:07", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-24T18:45:06", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-24T21:29:29", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-25T02:05:38", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-25T16:31:35", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-25T16:52:59", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-25T23:23:29", + "normal": 9.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-26T10:15:03", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-26T13:15:18", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-26T13:53:04", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-26T15:43:54", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-26T20:06:36", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-27T12:42:46", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-27T15:48:19", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-27T15:53:18", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-27T23:14:39", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-28T02:49:38", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-28T14:15:39", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-28T15:36:19", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-28T17:22:40", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-28T23:33:46", + "normal": 6.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-29T12:43:56", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-29T14:24:57", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-29T16:00:35", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-29T22:51:00", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-30T16:41:59", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-30T23:51:20", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-01T00:40:06", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-01T02:19:29", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-01T15:47:28", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-01T17:58:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-02T01:01:32", + "duration": 5400000, + "extended": 1.85, + "normal": 0.05, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-02T14:35:54", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-02T16:30:55", + "normal": 1.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-02T18:03:13", + "normal": 2.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-02T18:30:32", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-02T22:44:03", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-03T13:28:40", + "normal": 7.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-03T22:38:40", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-04T06:40:11", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-04T12:09:02", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-04T12:42:38", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-04T13:58:04", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-04T19:31:20", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-05T13:12:58", + "normal": 5.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-05T17:02:00", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-05T22:18:24", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-06T12:34:16", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-06T20:28:21", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-06T21:05:28", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-07T10:11:40", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-07T12:47:09", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-07T20:59:51", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-07T21:46:06", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-08T07:29:03", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-08T13:44:00", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-08T20:00:38", + "normal": 2.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-09T14:28:06", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-09T23:50:14", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-10T10:13:12", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-10T12:28:54", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-10T14:38:18", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-10T18:48:40", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-10T19:22:11", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-10T20:10:02", + "normal": 0.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-10T20:43:41", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-11T02:11:06", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-11T15:22:52", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-11T19:51:32", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-11T20:01:17", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-11T21:07:27", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-11T22:40:53", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-12T00:51:28", + "normal": 5.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-12T09:31:50", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-12T17:24:32", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-12T17:31:58", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-12T19:20:54", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-12T20:09:19", + "normal": 6.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-12T23:53:39", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-13T06:04:08", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-13T09:33:30", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-13T10:02:35", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-13T13:25:22", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-13T14:39:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-13T21:27:31", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-13T21:49:54", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-14T06:30:45", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-14T17:13:50", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-14T19:51:30", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-15T02:59:12", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-15T18:34:17", + "normal": 8.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-15T20:03:48", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-15T20:13:10", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-15T21:08:56", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-15T21:38:31", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-16T11:44:10", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-16T13:54:41", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-16T17:33:07", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-16T18:59:52", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-16T22:40:06", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-17T10:47:43", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-17T17:33:07", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-17T21:09:30", + "normal": 8.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-17T21:38:23", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-18T14:40:29", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-18T16:20:15", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-18T17:18:29", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-18T21:04:49", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-19T08:29:53", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-19T10:55:07", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-19T13:03:51", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-19T20:15:44", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-19T20:28:37", + "normal": 10.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-20T00:18:39", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-20T01:24:17", + "normal": 0.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-20T07:49:45", + "normal": 0.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-20T11:51:55", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-20T12:13:22", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-20T14:57:44", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-20T18:03:00", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-21T10:31:41", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-21T13:57:19", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-21T19:23:59", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-21T22:46:23", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-22T09:51:09", + "normal": 9.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-22T19:41:23", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-22T22:49:19", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-23T07:43:22", + "normal": 5.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-23T15:05:51", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-23T16:43:30", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-23T20:24:21", + "normal": 10.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-23T20:36:41", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-24T01:31:04", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-24T12:17:15", + "normal": 4.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-24T13:52:54", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-24T22:00:26", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-24T22:31:42", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-25T07:08:36", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-25T09:25:26", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-25T10:43:07", + "duration": 3600000, + "extended": 2.15, + "normal": 6.35, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-25T15:29:54", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-25T19:28:58", + "normal": 4.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-25T21:48:56", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-26T07:47:05", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-26T15:09:57", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-26T15:23:19", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-26T19:21:32", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-26T22:54:32", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-27T08:07:50", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-27T12:47:09", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-27T13:23:20", + "normal": 1.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-27T17:55:40", + "normal": 7.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-27T19:30:40", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-27T22:57:00", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-28T02:25:19", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-28T16:54:27", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-28T17:18:04", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-28T19:15:15", + "normal": 6.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-28T20:51:16", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-28T23:10:50", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-29T01:18:06", + "normal": 1.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-29T14:47:42", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-29T16:34:10", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-29T22:26:32", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-31T04:03:49", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-31T10:56:21", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-31T13:27:12", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-31T19:41:58", + "normal": 2.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-31T21:08:12", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-31T22:40:45", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-31T23:11:40", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-01T11:33:30", + "normal": 2.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-01T20:49:42", + "normal": 5.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-01T23:31:41", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-02T02:42:26", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-02T03:08:32", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-02T12:36:04", + "normal": 7.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-02T13:23:44", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-02T20:07:26", + "normal": 7.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-03T15:01:33", + "normal": 0.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-03T15:46:39", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-03T16:41:33", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-03T17:18:38", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-03T17:43:38", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-04T10:16:53", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-04T14:50:00", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-04T16:14:19", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-04T19:21:41", + "normal": 8.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-04T23:46:41", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-05T00:44:34", + "expectedNormal": 2, + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-05T01:02:58", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-05T12:01:09", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-05T12:23:18", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-05T12:51:54", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-05T15:39:48", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-05T21:29:36", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-06T04:21:34", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-06T08:53:58", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-07T15:08:48", + "normal": 0.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-10T19:54:26", + "normal": 7.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-08T15:53:04", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-08T22:22:31", + "normal": 7.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-08T22:47:20", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-09T15:51:36", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-10T00:59:27", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-10T10:23:36", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-10T18:30:44", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-10T18:39:41", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-10T19:47:34", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-11T13:53:18", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-11T20:58:05", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-12T00:35:54", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-12T13:04:51", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-12T17:37:35", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-12T19:09:48", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-12T19:34:40", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-13T00:02:43", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-13T00:11:41", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-13T08:33:39", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-13T20:19:52", + "duration": 1800000, + "extended": 2.55, + "normal": 0.6, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-14T16:44:31", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-14T22:46:55", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-15T00:28:57", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-15T08:51:33", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-15T11:33:53", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-15T19:09:51", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-16T17:02:11", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-16T18:49:50", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-16T20:22:02", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-17T11:14:04", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-17T19:29:27", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-18T06:45:25", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-18T15:28:35", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-18T16:20:17", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-18T16:50:44", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-18T22:16:57", + "duration": 3600000, + "extended": 4.2, + "normal": 2.8, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-19T07:18:23", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-19T18:51:48", + "normal": 4.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-20T08:50:29", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-20T11:19:38", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-20T15:42:53", + "duration": 1800000, + "extended": 0.45, + "normal": 1.3, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-20T17:25:24", + "duration": 3600000, + "extended": 0.75, + "normal": 3, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-20T21:38:30", + "duration": 3600000, + "extended": 2.85, + "normal": 6.55, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-21T11:54:08", + "duration": 3600000, + "extended": 2.8, + "normal": 2.8, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-21T14:39:04", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-21T18:23:31", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-21T19:29:16", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-21T20:00:12", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-21T21:40:40", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-21T23:42:55", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-22T00:24:30", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-22T08:20:59", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-22T21:37:44", + "duration": 3600000, + "extended": 1.2, + "normal": 4.8, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-22T22:25:47", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-22T23:37:05", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-23T07:32:39", + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-23T19:09:07", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-23T20:27:18", + "duration": 3600000, + "extended": 1.75, + "normal": 3.25, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-23T22:28:35", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-23T23:23:04", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T08:19:28", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T09:04:06", + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T10:00:56", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T18:30:46", + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T19:44:10", + "normal": 1.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T20:32:30", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T20:39:38", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-25T09:17:23", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-25T16:59:11", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-25T17:49:12", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-25T19:55:43", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-26T03:01:17", + "normal": 1.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-26T07:05:35", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-26T09:44:50", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-27T16:48:06", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-27T17:13:45", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-27T17:57:18", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-27T22:06:32", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-28T15:46:44", + "normal": 6.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-28T16:18:13", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-28T16:23:18", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-28T16:28:41", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-29T18:27:23", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-30T12:43:51", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-01T17:46:55", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-01T18:30:32", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-01T18:51:38", + "normal": 4.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-02T00:15:19", + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-02T06:49:58", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-02T18:35:00", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-03T12:03:51", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-03T12:50:24", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-03T17:08:12", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-03T17:41:00", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-03T19:08:04", + "expectedNormal": 2, + "normal": 0.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-03T19:08:18", + "normal": 0.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-04T01:21:22", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-04T14:10:31", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-04T17:59:30", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-04T19:21:37", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-04T19:25:51", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-04T20:09:01", + "normal": 7.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-05T02:02:39", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-05T02:36:40", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-05T13:58:30", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-05T17:17:54", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-05T23:40:50", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-06T01:28:33", + "normal": 3.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-06T14:59:11", + "normal": 2.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-06T20:26:50", + "duration": 3600000, + "extended": 2, + "normal": 6, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-07T00:48:50", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-07T14:09:43", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-07T16:02:12", + "duration": 5400000, + "extended": 3.25, + "normal": 9.75, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-08T18:17:26", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-08T18:29:06", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-08T20:29:43", + "normal": 5.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-08T23:53:16", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-09T12:19:24", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-09T16:27:30", + "duration": 3600000, + "extended": 1, + "normal": 5.65, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-09T17:50:34", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-10T00:25:49", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-10T17:43:21", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-10T18:08:03", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-11T13:06:32", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-11T19:37:52", + "normal": 7.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-12T00:07:01", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-12T00:42:51", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-12T07:40:06", + "normal": 3.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-12T08:50:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-12T16:09:42", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-12T21:45:57", + "normal": 6.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-13T10:56:43", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-13T11:42:47", + "normal": 1.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-13T16:33:50", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-13T18:21:41", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-13T22:13:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-13T22:19:30", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-13T22:48:14", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-13T23:08:30", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-14T14:31:41", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-14T15:53:20", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-14T17:37:39", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-14T18:15:11", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-14T20:29:30", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-15T12:18:56", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-15T14:09:52", + "normal": 4.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-15T17:23:04", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-15T21:15:01", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-15T21:44:35", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-15T22:12:37", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-15T22:57:20", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-15T22:58:49", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-16T09:35:57", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-16T11:31:07", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-16T15:12:49", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-16T15:41:21", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-16T21:04:38", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-17T03:22:39", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-17T14:09:57", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-17T16:29:43", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-18T05:26:35", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-18T08:03:17", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-18T17:58:39", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-18T20:40:22", + "duration": 1800000, + "extended": 5.7, + "normal": 1.9, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-19T08:36:08", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-19T15:20:39", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-19T18:22:28", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-19T18:54:15", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-19T22:20:06", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-19T22:47:22", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-20T14:23:03", + "duration": 3600000, + "extended": 1.35, + "normal": 5.4, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-20T15:02:15", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-20T15:50:21", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-21T00:08:35", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-21T12:12:24", + "normal": 5.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-21T15:13:53", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-22T16:11:14", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-23T01:06:51", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-23T10:37:02", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-23T16:18:09", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-23T16:57:31", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-23T21:30:01", + "duration": 1800000, + "extended": 3.55, + "normal": 1.15, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-24T08:03:19", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-24T13:21:49", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-24T13:41:26", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-24T15:13:42", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-24T17:30:34", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-24T18:47:01", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-25T00:37:32", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-25T15:27:34", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-25T15:50:46", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-25T18:34:45", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-26T08:00:02", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-26T15:30:21", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-26T16:43:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-26T22:55:06", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-27T00:34:23", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-27T16:08:38", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-28T10:22:34", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-28T10:42:12", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-28T11:14:05", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-28T12:22:02", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-28T17:58:24", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-29T00:59:10", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-29T13:21:48", + "normal": 3.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-29T14:26:37", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-29T15:29:23", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-29T19:11:00", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-29T21:59:18", + "duration": 10800000, + "extended": 8.65, + "normal": 2.85, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-30T07:29:04", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-30T11:32:41", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-30T13:33:42", + "normal": 2.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-30T15:10:57", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-30T16:48:04", + "duration": 2700000, + "expectedDuration": 3600000, + "expectedExtended": 2.65, + "extended": 1.95, + "normal": 4.5, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-30T17:35:25", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-31T06:01:14", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-31T08:02:24", + "expectedNormal": 1.8, + "normal": 0, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-31T17:32:27", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-31T19:24:54", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-31T20:15:14", + "normal": 7.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-31T23:11:02", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-01T15:38:03", + "normal": 7.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-02T00:53:24", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-02T09:42:56", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-02T12:33:40", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-03T13:13:56", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-03T13:30:33", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-03T19:02:46", + "normal": 7.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-03T23:23:36", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-03T23:30:48", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-04T07:57:10", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-04T17:05:51", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-04T18:14:03", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-05T16:45:27", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-05T19:47:08", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-06T09:25:42", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-06T15:20:44", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-06T16:19:31", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-06T17:07:49", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-06T19:58:23", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-07T14:38:43", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-07T19:47:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-07T20:51:30", + "normal": 8.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-07T21:31:38", + "normal": 5.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-08T01:05:38", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-08T10:11:09", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-08T15:43:17", + "normal": 6.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-08T19:52:56", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-08T20:57:40", + "duration": 3600000, + "extended": 2, + "normal": 8.95, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-09T09:07:47", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-09T16:17:45", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-09T17:24:45", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-11T01:12:55", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-11T18:24:34", + "normal": 5.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-11T19:04:48", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-11T20:30:46", + "normal": 0.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-12T10:04:06", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-13T17:30:51", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-13T18:15:01", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-13T18:43:29", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-14T15:37:44", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-15T01:47:54", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-15T13:59:56", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-15T14:41:43", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-15T14:44:38", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-15T21:54:18", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-16T15:51:57", + "normal": 7.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-16T16:23:22", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-16T20:59:44", + "normal": 7.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-16T22:28:09", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-17T13:43:39", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-17T15:22:58", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-17T20:43:00", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-17T22:37:07", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-18T12:51:55", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-18T15:37:39", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-18T16:20:47", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-18T16:23:34", + "expectedNormal": 1, + "normal": 0, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-18T16:23:47", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-19T01:18:52", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-19T18:35:04", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-19T18:45:16", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-19T19:19:18", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-19T19:49:49", + "normal": 9.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-20T13:23:57", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-20T18:56:03", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-21T18:29:04", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-21T20:46:21", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-22T21:10:05", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-22T21:58:04", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-22T22:02:55", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-23T18:27:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-23T20:31:41", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-23T20:59:54", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-23T23:21:11", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-24T10:24:29", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-24T17:07:32", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-24T17:33:08", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-24T18:35:51", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-25T14:07:13", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-25T17:12:17", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-25T21:24:58", + "normal": 8.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-26T11:35:34", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-26T11:48:12", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-26T12:08:19", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-26T16:13:11", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-26T22:12:41", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-27T01:27:13", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-27T16:56:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-27T19:56:41", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-27T20:22:28", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-27T20:57:07", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-28T07:42:06", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-28T09:05:30", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-28T09:54:05", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-28T14:01:25", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-28T15:50:43", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-28T20:59:49", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-28T21:29:58", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-29T01:28:07", + "expectedNormal": 3, + "normal": 0, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-29T01:28:23", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-29T05:09:40", + "expectedNormal": 2.55, + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-29T05:18:26", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-29T06:58:48", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-29T07:02:43", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-29T13:23:14", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-29T21:18:42", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-30T15:27:04", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-30T15:45:46", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-30T16:03:48", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-30T21:27:24", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-31T00:32:49", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-31T14:12:55", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-01T00:10:43", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-01T00:20:00", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-01T01:11:31", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-01T18:11:06", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-01T18:59:49", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-01T23:21:40", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T01:17:05", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T07:22:03", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T09:19:07", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T15:32:12", + "duration": 3600000, + "extended": 1.65, + "normal": 3.8, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T17:09:29", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T19:39:58", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T20:38:24", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T20:44:02", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T21:40:20", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-03T00:20:40", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-03T06:42:57", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-03T14:08:27", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-03T14:48:55", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-03T17:14:46", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-03T22:34:31", + "normal": 5.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-04T00:28:34", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-04T06:09:22", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-04T14:45:39", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-04T18:24:53", + "normal": 10.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-05T01:06:54", + "normal": 6.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-05T16:22:33", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-05T16:58:48", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-05T21:45:50", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-06T00:55:25", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-06T15:41:42", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-06T15:45:31", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-06T16:47:53", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-06T21:15:40", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-07T19:12:03", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-07T19:57:42", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-07T20:27:57", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-07T23:09:54", + "normal": 10.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-08T06:49:54", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-08T13:38:14", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-08T19:03:48", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-08T21:12:03", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-08T22:21:55", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-09T01:19:46", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-09T15:05:45", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-09T22:54:59", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-09T23:26:51", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-10T16:45:44", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-10T17:22:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-10T20:02:24", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-10T22:48:01", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-10T23:18:10", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-11T17:11:53", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-11T23:15:24", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-12T00:04:13", + "normal": 2.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-12T00:28:22", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-12T15:21:56", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-13T15:59:02", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-13T22:06:29", + "normal": 6.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-14T11:11:32", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-14T13:09:35", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-14T19:24:39", + "normal": 10.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-15T15:36:19", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-15T21:46:47", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-15T22:10:16", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-16T15:44:33", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-16T21:36:53", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-17T15:59:12", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-17T16:08:56", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-17T21:09:25", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-18T09:37:49", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-18T18:20:54", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-18T18:51:09", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-19T13:27:26", + "duration": 3600000, + "extended": 0.55, + "normal": 0.25, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-19T14:53:40", + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-19T15:24:30", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-20T18:32:41", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-20T21:29:36", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-21T15:35:49", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-21T21:03:52", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-21T22:39:49", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-22T11:25:56", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-22T13:19:40", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-22T17:25:35", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-22T19:59:31", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-22T22:50:19", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-23T11:45:40", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-23T11:47:49", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-23T12:07:32", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-23T15:08:45", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-23T20:33:01", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-23T22:00:40", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-24T06:08:59", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-24T08:33:59", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-24T11:22:33", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-24T21:52:26", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-24T22:08:46", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-25T16:52:46", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-25T20:23:33", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-25T20:36:44", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-26T07:18:20", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-26T10:15:04", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-26T16:11:43", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-26T19:25:09", + "normal": 6.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-26T21:22:26", + "normal": 1.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-27T12:14:07", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-27T13:57:02", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-27T14:09:20", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-27T15:29:54", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-27T20:48:41", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-27T21:12:09", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-27T21:20:49", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-27T21:49:25", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-28T04:50:11", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-28T07:40:45", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-28T12:06:19", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-28T15:46:19", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-28T21:47:01", + "normal": 12.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-29T01:12:35", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-29T02:08:17", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-29T02:59:26", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-29T14:42:33", + "normal": 7.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-29T15:02:43", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-29T15:12:10", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-29T19:10:18", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-29T19:46:49", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-30T11:29:40", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-30T13:56:15", + "normal": 5.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-30T15:42:59", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-30T22:53:22", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-30T23:05:22", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-30T23:35:16", + "normal": 7.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-01T14:27:43", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-01T16:04:42", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-01T22:28:45", + "normal": 6.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-02T17:01:12", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-02T18:18:32", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-02T22:08:17", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-02T22:56:37", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-03T07:44:00", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-03T08:42:58", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-03T15:24:28", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-03T17:53:59", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-03T19:00:37", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-03T22:17:33", + "normal": 7.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-04T09:52:11", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-04T12:55:58", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-04T15:12:11", + "normal": 6.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-04T20:09:22", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-05T03:27:19", + "normal": 4.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-05T19:22:47", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-05T22:39:45", + "normal": 10.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-06T06:12:37", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-06T12:42:06", + "normal": 8.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-06T15:32:00", + "expectedNormal": 4.7, + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-06T19:07:20", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-06T19:39:58", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-07T00:20:47", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-07T05:30:49", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-07T08:21:15", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-07T22:44:14", + "normal": 8.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-08T06:58:25", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-08T08:16:59", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-08T13:52:10", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-08T19:52:08", + "normal": 5.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-09T06:26:22", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-09T07:43:04", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-09T15:08:46", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-09T15:54:44", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-09T23:03:47", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-09T23:38:04", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-10T16:02:43", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-10T22:56:35", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-10T23:35:59", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-11T15:03:25", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-11T16:13:04", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-11T21:19:03", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-12T07:22:58", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-12T15:16:54", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-12T15:54:25", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-12T21:11:04", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-13T13:15:55", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-13T13:18:43", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-13T16:26:19", + "normal": 6.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-13T20:33:47", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-13T20:49:06", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-13T21:24:48", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-13T23:18:40", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-13T23:45:17", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-14T00:25:53", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-14T01:10:52", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-14T12:00:00", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-14T15:36:08", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-14T16:01:10", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-14T19:58:59", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-14T20:51:48", + "normal": 8.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-14T21:40:26", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-14T23:14:13", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-15T00:33:52", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-15T08:45:17", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-15T15:49:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-15T21:53:25", + "normal": 8.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-15T22:38:18", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-16T16:47:33", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-16T22:22:47", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-16T23:27:48", + "normal": 14.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-17T15:50:12", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-17T15:52:31", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-18T14:12:19", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-18T15:09:54", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-18T15:27:12", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-18T15:57:46", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-18T23:28:05", + "normal": 8.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-19T00:10:14", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-19T00:46:24", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-19T01:11:02", + "normal": 5.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-19T14:59:14", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-19T16:28:00", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-19T22:00:22", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-19T23:24:34", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-20T17:39:33", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-20T19:27:43", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-20T20:07:49", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-20T20:43:12", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-20T21:54:33", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-21T14:16:42", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-21T20:42:35", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-22T12:14:12", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-23T07:12:15", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-23T11:12:32", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-23T12:36:16", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-23T12:50:53", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-23T14:17:09", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-24T10:47:06", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-24T14:20:06", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-24T16:11:40", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-25T00:18:43", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-25T19:12:42", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-25T20:42:26", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-26T18:49:01", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-27T18:11:11", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-27T20:47:51", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-28T13:28:57", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-28T13:31:35", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-28T13:43:39", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-28T18:08:08", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-29T03:56:45", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-29T15:09:37", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-29T15:58:27", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-30T02:57:09", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-30T16:34:05", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-30T19:17:07", + "expectedNormal": 8, + "normal": 6.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-30T23:28:05", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-31T20:19:12", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-01T16:10:05", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-01T23:01:05", + "normal": 3.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-02T17:16:10", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-02T23:46:20", + "normal": 8.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-03T12:56:37", + "normal": 6.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-03T13:09:30", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-03T16:07:02", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-03T20:10:25", + "duration": 3600000, + "extended": 2.2, + "normal": 12.3, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-04T05:00:38", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-04T12:35:17", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-04T15:46:38", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-04T22:01:14", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-05T09:37:58", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-05T13:19:18", + "normal": 2, + "subType": "normal", + }, +} + +var PlatformBolusSet = []map[string]interface{}{ + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-11T05:48:32", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-11T05:48:32", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-11T08:48:43", + "normal": 2.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-11T08:48:43", + "normal": 2.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-11T17:07:35", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-11T17:48:17", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-11T22:16:32", + "expectedNormal": 6, + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T02:48:01", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T02:57:56", + "normal": 2.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T02:57:56", + "normal": 2.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T03:45:23", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T04:02:33", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T04:02:33", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T04:07:54", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T12:10:52", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T12:10:52", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T13:43:31", + "normal": 0.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T13:43:31", + "normal": 0.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T18:55:53", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-12T22:06:00", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-13T00:07:54", + "normal": 6.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-13T15:36:15", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-13T15:36:15", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-13T19:15:32", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-13T23:32:46", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-14T02:56:18", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-14T15:05:16", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-14T15:05:16", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-14T18:45:59", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-14T21:06:30", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-15T02:10:44", + "expectedNormal": 6, + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-15T10:11:52", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-15T10:21:08", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-15T10:52:13", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-15T18:51:32", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-15T20:32:07", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-15T20:43:33", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-15T20:43:33", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-15T21:26:55", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-16T07:56:57", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-16T07:56:57", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-16T15:32:09", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-16T15:32:09", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-16T16:04:19", + "expectedNormal": 3.7, + "normal": 0.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-16T16:04:45", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-16T16:23:41", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-16T16:35:34", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-16T16:58:46", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-16T22:04:48", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T07:49:22", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T07:49:22", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T07:58:22", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T08:31:44", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T09:25:59", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T15:19:35", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T15:41:16", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T16:13:32", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T16:51:39", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T17:36:34", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-17T22:24:30", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-18T00:26:16", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-18T00:57:05", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-18T09:39:10", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-18T13:26:16", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-18T15:56:31", + "normal": 0.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-18T15:56:31", + "normal": 0.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-18T16:46:24", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-18T17:16:59", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-18T17:16:59", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-19T01:21:09", + "normal": 2.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-19T01:21:09", + "normal": 2.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-19T01:51:44", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-19T18:01:16", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-19T19:01:35", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-19T22:24:42", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-19T22:27:54", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-19T23:16:39", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-20T11:50:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-20T13:36:40", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-20T13:36:40", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-20T18:31:12", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-20T19:04:49", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-20T19:13:53", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-21T14:16:39", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-22T00:12:03", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-22T00:12:03", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-22T13:54:39", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-22T20:02:33", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-22T20:09:02", + "normal": 7.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-22T20:42:46", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-22T20:51:20", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-23T14:51:38", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-23T14:51:38", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-23T17:40:56", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-24T10:57:40", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-24T13:49:15", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-24T13:49:15", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-24T20:29:08", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-24T20:29:08", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-24T23:20:14", + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-24T23:20:14", + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T02:11:25", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T02:11:25", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T03:41:15", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T03:49:26", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T11:34:54", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T11:36:30", + "expectedNormal": 3.7, + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T11:39:54", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T18:55:44", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T21:00:32", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T21:56:23", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-25T22:40:16", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-26T00:47:19", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-26T11:19:24", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-26T11:19:24", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-26T18:22:46", + "normal": 9.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-26T18:22:46", + "normal": 9.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-26T20:06:31", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-26T21:00:39", + "normal": 4.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-27T00:43:11", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-27T00:54:23", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-27T01:21:34", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-27T01:21:34", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-27T07:02:47", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-27T08:20:19", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-27T08:20:19", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-27T11:57:25", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-27T18:36:04", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-27T20:18:11", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-28T10:55:51", + "normal": 10.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-28T13:31:27", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-28T17:47:15", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-28T18:58:25", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-28T20:20:09", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T05:47:36", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T11:04:51", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T11:17:10", + "expectedNormal": 5, + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T11:17:44", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T11:59:21", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T11:59:21", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T12:33:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T16:04:51", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T18:22:02", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T18:22:02", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-29T20:35:15", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-30T00:19:10", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-30T01:14:53", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-30T11:38:04", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-30T11:38:04", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-30T14:10:30", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-30T18:11:40", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-30T19:40:37", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-11-30T22:39:58", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-01T09:55:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-01T12:02:23", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-01T12:02:23", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-01T12:11:07", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-01T15:03:11", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-01T23:36:08", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-02T13:42:27", + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-02T13:42:27", + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-03T08:36:32", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-03T12:46:16", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-03T14:31:00", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-03T19:01:03", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-03T19:13:12", + "duration": 3600000, + "extended": 1.35, + "normal": 3.25, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-03T19:13:12", + "duration": 3600000, + "extended": 1.35, + "normal": 3.25, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-03T23:09:17", + "expectedNormal": 5.6, + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-03T23:09:17", + "expectedNormal": 5.6, + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-04T01:32:34", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-04T13:31:48", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-04T23:45:20", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-05T05:38:22", + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-05T05:38:22", + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-05T13:05:36", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-05T18:04:44", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-05T22:31:49", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-06T09:05:49", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-06T19:44:34", + "normal": 3.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-06T19:44:34", + "normal": 3.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-07T11:30:47", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-07T17:39:58", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-08T09:36:46", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-08T09:36:46", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-08T12:09:06", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-08T13:51:33", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-08T13:51:33", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-08T22:47:22", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-08T23:06:37", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-08T23:34:05", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-09T11:51:03", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-09T18:28:48", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-09T18:41:43", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-09T19:46:42", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-09T19:46:42", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-09T22:41:34", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-10T03:05:28", + "normal": 1.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-10T03:05:28", + "normal": 1.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-10T11:34:38", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-10T14:55:50", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-10T15:23:08", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-10T19:28:56", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-10T21:16:11", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-10T22:17:25", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-11T14:30:42", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-11T19:17:18", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-12T13:15:43", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-12T14:37:19", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-12T20:45:23", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-12T21:17:50", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-12T22:07:50", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-12T23:57:33", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-12T23:57:33", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-13T10:28:04", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-13T10:28:04", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-13T17:42:12", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-14T04:31:16", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-14T09:40:01", + "normal": 3.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-14T09:40:01", + "normal": 3.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-14T15:57:40", + "normal": 2.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-14T15:57:40", + "normal": 2.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-14T17:26:58", + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-14T17:26:58", + "normal": 2.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-15T05:49:43", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-15T09:42:54", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-15T09:42:54", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-15T15:42:11", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-15T17:58:05", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-15T20:36:40", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-15T21:54:57", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-16T02:10:54", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-16T05:18:35", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-16T05:18:35", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-16T17:03:43", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-16T21:17:40", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-16T21:27:12", + "expectedNormal": 1.8, + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-17T15:02:37", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-17T15:02:37", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-18T08:53:51", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-18T08:53:51", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-18T14:07:21", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-18T14:07:21", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-19T00:37:12", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-20T22:52:22", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-20T22:52:22", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-21T16:04:44", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-21T16:04:44", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-21T17:31:36", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-22T20:34:13", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T00:32:29", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T00:32:29", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T02:01:53", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T02:01:53", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T13:25:12", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T14:45:29", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T14:45:29", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T15:17:41", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T15:27:27", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T20:51:42", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T20:51:42", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T22:28:05", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-23T22:28:05", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-24T15:45:49", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-24T15:45:49", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-24T17:30:54", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-25T03:24:31", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-25T17:51:24", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-25T18:17:02", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-25T18:44:42", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-25T19:06:09", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-26T04:38:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-26T21:52:20", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-26T22:10:35", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-27T00:35:55", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-27T12:09:08", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-27T13:12:31", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-27T22:06:04", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-27T23:57:59", + "normal": 8.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-27T23:57:59", + "normal": 8.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-28T13:41:05", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-28T13:41:05", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-28T21:53:48", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-28T21:53:48", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-28T22:38:58", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-28T23:35:34", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-29T01:10:10", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-29T13:28:49", + "normal": 7.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-29T15:31:09", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-29T15:47:25", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-29T20:49:26", + "normal": 10.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-29T20:49:26", + "normal": 10.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-29T23:31:22", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T01:14:51", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T01:14:51", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T10:07:54", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T14:41:41", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T14:41:41", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T15:36:28", + "normal": 0.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T15:36:28", + "normal": 0.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T17:21:07", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T17:47:07", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T17:47:07", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T19:43:22", + "normal": 10.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T21:42:19", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T23:34:45", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-30T23:57:13", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-31T14:15:24", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-31T15:37:20", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-31T16:37:23", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-31T20:22:35", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2017-12-31T22:50:28", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-01T00:18:37", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-01T03:28:56", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-01T08:23:20", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-01T17:09:58", + "normal": 5.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-01T17:09:58", + "normal": 5.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-01T20:29:55", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-01T21:39:29", + "normal": 11.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-01T21:39:29", + "normal": 11.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T01:37:45", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T01:37:45", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T09:05:27", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T09:05:27", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T09:28:02", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T09:28:02", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T15:17:44", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T15:17:44", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T17:05:07", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T21:57:29", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T21:57:29", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T22:31:41", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T23:58:14", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-02T23:58:14", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-03T06:23:16", + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-03T06:23:16", + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-03T13:07:10", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-03T13:07:10", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-03T17:36:24", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-03T17:36:24", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-03T19:19:53", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-04T20:39:32", + "normal": 12.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-04T23:27:30", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-05T11:26:40", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-05T14:39:47", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-05T21:24:08", + "normal": 12.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-05T23:47:57", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-06T10:29:13", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-07T02:43:11", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-07T15:29:23", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-07T15:53:38", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-08T00:50:58", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-08T02:22:40", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-08T10:49:22", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-08T12:10:15", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-08T16:06:15", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-08T21:00:55", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-08T22:52:11", + "normal": 13.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-09T06:48:05", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-09T11:57:20", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-09T14:50:09", + "expectedNormal": 7.1, + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-09T15:09:57", + "expectedNormal": 5.3, + "normal": 0, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-09T15:10:07", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-09T15:45:24", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-09T19:08:06", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-10T00:20:48", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-10T09:57:07", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-10T15:19:38", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-10T15:19:38", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-10T19:51:35", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-10T21:04:03", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-11T17:21:27", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-11T23:50:01", + "normal": 9.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-11T23:50:01", + "normal": 9.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-12T14:21:27", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-13T01:22:50", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-13T09:16:42", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-13T09:45:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-13T17:59:12", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-13T19:51:42", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-14T01:09:36", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-14T01:09:36", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-14T15:27:34", + "normal": 6.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-14T15:37:30", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-14T19:52:15", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-14T22:44:38", + "normal": 11, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-14T23:04:59", + "expectedNormal": 8.7, + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-15T08:08:01", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-15T08:08:01", + "normal": 5.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-15T17:50:26", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-15T18:22:34", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-15T22:12:43", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-16T05:28:57", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-16T19:06:03", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-18T00:44:27", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-18T00:44:27", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-18T15:16:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-18T21:34:19", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-19T15:18:48", + "normal": 7.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-19T15:18:48", + "normal": 7.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-19T18:24:25", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-19T21:40:18", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-20T01:57:09", + "normal": 5.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-20T01:57:09", + "normal": 5.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-20T05:21:15", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-20T14:43:26", + "normal": 2.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-20T14:43:26", + "normal": 2.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-20T20:23:29", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-20T23:15:21", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-21T01:47:25", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-21T01:47:25", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-21T16:32:58", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-21T16:32:58", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-21T21:12:41", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-22T13:07:23", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-22T13:24:37", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-22T13:38:43", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-22T13:38:43", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-22T14:23:46", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-23T00:01:17", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-23T02:53:10", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-23T10:26:09", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-23T12:45:53", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-23T19:04:33", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-24T02:03:30", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-24T02:03:30", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-24T08:42:05", + "normal": 3.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-24T08:42:05", + "normal": 3.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-24T09:11:28", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-24T13:05:25", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-24T16:20:41", + "normal": 0.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-24T16:20:41", + "normal": 0.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-24T19:39:24", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-24T22:58:57", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-24T22:58:57", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-25T09:05:32", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-25T09:15:49", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-25T10:05:32", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-25T15:20:46", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-26T00:34:00", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-26T00:40:32", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-26T17:42:21", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-27T00:26:46", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-27T01:56:53", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-27T15:00:57", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-27T16:30:36", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-28T00:07:24", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-28T04:04:35", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-28T11:06:58", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-28T12:05:56", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-28T17:32:14", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-28T22:51:31", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-29T09:24:11", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-29T11:48:49", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-01-31T17:35:53", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-01T22:39:45", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-01T23:11:22", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-02T05:32:22", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-02T13:53:59", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-02T15:01:02", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-03T11:47:19", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-03T17:52:13", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-04T00:51:30", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-04T01:35:03", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-04T10:23:28", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-05T00:40:31", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-05T22:10:18", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-06T00:30:31", + "duration": 9000000, + "extended": 2.4, + "normal": 0.1, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-06T00:30:31", + "duration": 9000000, + "extended": 2.4, + "normal": 0.1, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-06T11:27:46", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-06T12:24:47", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-06T12:24:47", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-06T21:00:06", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-06T21:26:09", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-06T22:30:08", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-07T01:20:24", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-07T01:20:24", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-07T15:08:42", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-07T17:35:21", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-07T17:35:21", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-08T00:40:52", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-08T00:40:52", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-08T04:05:56", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-08T04:08:07", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-08T20:24:34", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-08T21:17:19", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-09T03:41:21", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-09T03:43:00", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-09T15:27:27", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-09T15:27:27", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-09T16:50:23", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-10T00:06:05", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-10T07:13:02", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-10T10:23:08", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-11T01:16:30", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-11T13:20:10", + "normal": 1.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-11T13:20:10", + "normal": 1.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-11T17:04:18", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-11T19:38:24", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-11T20:40:19", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-11T22:22:57", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-11T23:03:25", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-12T10:31:15", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-12T10:47:00", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-12T17:15:24", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-12T22:52:54", + "duration": 5400000, + "extended": 3.6, + "normal": 0.4, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-12T22:52:54", + "duration": 5400000, + "extended": 3.6, + "normal": 0.4, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-12T23:37:16", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-13T03:06:20", + "expectedNormal": 2.4, + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-13T04:51:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-13T19:40:33", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-13T20:05:03", + "normal": 0.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-14T17:20:11", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-14T17:56:34", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-15T01:56:38", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-15T17:29:22", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-16T09:23:19", + "normal": 2.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-16T09:23:19", + "normal": 2.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-17T11:56:27", + "normal": 0.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-17T11:56:27", + "normal": 0.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-18T00:34:51", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-18T04:32:23", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-18T12:15:36", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-18T12:56:37", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-18T20:43:52", + "normal": 9.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-19T03:06:10", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-19T17:37:52", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-19T17:37:52", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-19T18:33:24", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-19T22:24:06", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-19T23:15:16", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-19T23:57:50", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-20T11:27:44", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-20T12:13:32", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-20T17:12:58", + "normal": 7.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-20T17:12:58", + "normal": 7.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-20T23:25:38", + "normal": 4.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-20T23:25:38", + "normal": 4.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-21T18:12:48", + "normal": 4.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-21T23:02:43", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-22T05:11:08", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-22T12:46:46", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-22T18:44:55", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-22T23:47:30", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-23T15:22:30", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-24T01:28:13", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-24T04:50:59", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-24T04:50:59", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-24T10:06:16", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-24T10:57:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-24T16:20:38", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-24T20:57:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-24T21:10:06", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-25T01:46:05", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-25T03:01:41", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-25T03:01:41", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-25T12:45:34", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-25T16:35:50", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-25T16:43:09", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-26T14:50:38", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-26T23:18:20", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-27T19:10:37", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-27T19:56:05", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-27T20:05:22", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-02-27T20:33:26", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-01T11:06:45", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-01T13:38:00", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-01T13:38:00", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-01T17:26:06", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-02T05:10:59", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-02T14:53:50", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-02T15:15:41", + "duration": 7200000, + "extended": 4, + "normal": 2.65, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-02T15:15:41", + "duration": 7200000, + "extended": 4, + "normal": 2.65, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-02T17:55:24", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-02T21:27:07", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-02T21:27:07", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-03T02:23:28", + "normal": 3.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-03T02:23:28", + "normal": 3.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-03T07:55:24", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-03T13:31:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-03T17:33:40", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-04T01:00:34", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-04T09:51:54", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-04T13:59:53", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-04T14:53:15", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-04T17:26:51", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-04T19:38:13", + "normal": 8.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-04T23:09:52", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-04T23:57:26", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-04T23:57:26", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-05T03:09:50", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-05T14:54:46", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-05T18:29:31", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-06T00:34:35", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-06T01:21:36", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-06T06:12:45", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-06T19:38:19", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-07T08:26:18", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-07T10:24:27", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-07T16:59:43", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-07T22:10:21", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-07T23:47:40", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-08T00:47:32", + "duration": 10800000, + "extended": 1.65, + "subType": "square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-08T00:47:32", + "duration": 10800000, + "extended": 1.65, + "subType": "square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-08T17:20:24", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-08T23:16:45", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-08T23:16:45", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-09T09:43:12", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-09T19:36:18", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-09T21:47:07", + "normal": 11, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-09T22:28:29", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-10T00:56:27", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-10T05:18:33", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-10T10:09:03", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-10T19:08:41", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-10T19:30:42", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-10T21:00:08", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-10T21:11:26", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-11T00:12:25", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-11T00:12:25", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-11T03:50:32", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-11T09:48:55", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-11T17:56:25", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-11T21:45:42", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-11T23:48:21", + "normal": 7.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-11T23:59:24", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-12T11:02:19", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-12T14:13:44", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-12T23:30:03", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-13T00:01:21", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-13T08:23:02", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-13T15:29:58", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-13T16:25:10", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-14T01:00:14", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-14T01:48:33", + "duration": 7200000, + "extended": 5, + "subType": "square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-14T08:26:33", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-14T09:15:40", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-14T21:17:36", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-14T21:36:42", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-15T01:00:44", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-15T12:10:00", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-15T13:36:53", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-15T21:24:43", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-15T22:46:02", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-16T19:49:33", + "normal": 12.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-16T19:49:33", + "normal": 12.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-17T15:56:01", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-17T15:56:01", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-18T10:02:04", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-18T15:29:15", + "normal": 6.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-18T15:29:15", + "normal": 6.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-18T16:27:25", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-18T21:15:02", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-19T06:28:44", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-19T15:28:25", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-19T22:15:08", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-20T08:14:49", + "duration": 3600000, + "extended": 1.5, + "normal": 0.5, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-20T12:02:19", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-20T13:19:06", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-20T16:07:19", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-20T19:43:27", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-20T20:56:53", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-21T00:32:48", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-21T14:39:05", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-21T21:09:21", + "normal": 12, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-21T22:14:04", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-22T03:19:52", + "expectedNormal": 5.15, + "normal": 0.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-22T03:19:52", + "expectedNormal": 5.15, + "normal": 0.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-22T03:20:35", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-22T10:57:48", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-22T16:15:49", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-22T23:32:14", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-23T03:44:48", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-23T10:03:49", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-23T12:03:21", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-23T12:03:21", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-23T12:08:31", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-23T17:28:19", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-23T18:10:06", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-23T22:45:10", + "normal": 6.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-23T23:57:11", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-24T01:52:51", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-24T04:04:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-24T10:09:10", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-24T15:22:15", + "normal": 9.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-24T15:59:21", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-24T18:45:12", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-25T03:44:15", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-25T04:12:56", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-25T13:25:50", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-25T15:47:08", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-25T16:27:53", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-25T16:27:53", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-25T17:26:51", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-26T01:03:51", + "normal": 9.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-26T01:03:51", + "normal": 9.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-26T04:48:39", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-26T15:52:08", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-26T18:11:28", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-26T21:42:00", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-26T23:21:43", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-27T13:11:38", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-27T13:27:58", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-27T13:43:12", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-27T14:19:41", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-28T01:21:26", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-28T02:49:55", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-28T02:49:55", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-28T12:09:39", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-28T21:12:56", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-29T01:42:57", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-29T12:10:07", + "normal": 8.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-29T12:10:07", + "normal": 8.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-29T20:29:43", + "normal": 8.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-29T20:29:43", + "normal": 8.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-29T23:08:20", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-29T23:23:56", + "expectedNormal": 2, + "normal": 0.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-29T23:24:13", + "expectedNormal": 3.8, + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-29T23:25:03", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-30T09:17:33", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-30T11:41:40", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-30T18:46:16", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-30T22:26:35", + "normal": 7.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-30T22:26:35", + "normal": 7.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-31T09:34:04", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-31T11:02:09", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-03-31T18:03:31", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-01T13:35:12", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-01T19:00:43", + "expectedNormal": 5.5, + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-02T11:24:01", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-02T11:24:01", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-03T00:24:02", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-03T00:24:02", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-03T04:46:03", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-03T13:58:14", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-03T15:41:52", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-03T22:48:16", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-03T22:48:16", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-03T22:53:19", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-03T23:37:06", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-04T17:49:44", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-04T18:25:58", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-04T20:06:51", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-04T20:50:31", + "expectedNormal": 6.5, + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-04T21:47:42", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-05T11:10:22", + "normal": 8.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-05T13:57:52", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-05T14:41:02", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-05T19:55:35", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-05T20:07:23", + "normal": 6.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-05T20:07:23", + "normal": 6.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-05T23:10:52", + "normal": 10.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-05T23:10:52", + "normal": 10.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-06T17:04:13", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-07T00:30:35", + "normal": 13, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-07T11:30:23", + "expectedNormal": 11.3, + "normal": 7.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-07T11:30:23", + "expectedNormal": 11.3, + "normal": 7.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-07T13:39:36", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-07T15:31:20", + "normal": 7.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-07T17:03:27", + "normal": 6.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-07T19:36:38", + "normal": 11.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-07T19:36:38", + "normal": 11.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T02:04:38", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T02:04:38", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T11:36:22", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T11:36:22", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T15:35:43", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T16:36:54", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T17:06:19", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T17:06:19", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T18:36:43", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T20:45:53", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T21:43:56", + "normal": 5.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T22:27:26", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-08T22:27:26", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-09T13:34:32", + "normal": 4.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-09T13:34:32", + "normal": 4.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-09T23:51:42", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-10T11:33:52", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-10T15:06:31", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-10T16:39:01", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-10T23:28:10", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-10T23:28:10", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-10T23:56:06", + "normal": 3.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-10T23:56:06", + "normal": 3.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-11T08:31:34", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-11T14:14:04", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-11T21:33:10", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-11T21:33:10", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-12T13:11:06", + "normal": 5.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-12T15:22:32", + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-12T15:22:32", + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-12T20:37:48", + "duration": 3600000, + "extended": 1.4, + "normal": 4.1, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-12T20:37:48", + "duration": 3600000, + "extended": 1.4, + "normal": 4.1, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-13T07:00:52", + "normal": 2.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-13T07:00:52", + "normal": 2.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-13T11:55:34", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-13T15:38:33", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-13T15:38:33", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-13T16:43:21", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-13T22:25:40", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-13T23:43:31", + "duration": 3600000, + "extended": 3, + "normal": 4.5, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-13T23:43:31", + "duration": 3600000, + "extended": 3, + "normal": 4.5, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-14T07:24:30", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-14T11:26:07", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-14T14:02:33", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-14T16:13:29", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-14T16:21:37", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-15T04:30:42", + "normal": 2.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-15T04:30:42", + "normal": 2.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-15T11:27:28", + "normal": 9.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-15T21:09:40", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-15T21:29:47", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-16T08:42:28", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-16T08:42:28", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-16T09:08:02", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-16T18:50:11", + "normal": 7.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-16T18:50:11", + "normal": 7.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-16T22:19:29", + "normal": 8.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-16T22:19:29", + "normal": 8.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-17T07:49:58", + "expectedNormal": 6.25, + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-17T07:49:58", + "expectedNormal": 6.25, + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-17T10:22:10", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-17T15:38:57", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-17T16:53:15", + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-17T16:53:15", + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-17T23:01:44", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-17T23:01:44", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-17T23:17:46", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-18T03:36:54", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-18T08:15:40", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-18T13:03:08", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-18T13:03:08", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-18T22:49:11", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-19T10:49:57", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-19T10:49:57", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-19T12:47:07", + "normal": 7.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-19T12:47:07", + "normal": 7.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-19T18:51:49", + "normal": 0.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-19T18:51:49", + "normal": 0.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T00:34:12", + "normal": 4.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T00:34:12", + "normal": 4.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T11:55:56", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T11:55:56", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T12:21:25", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T12:25:59", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T12:40:44", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T16:51:52", + "normal": 5.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T16:51:52", + "normal": 5.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T17:13:53", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T18:53:57", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T21:13:02", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T21:17:28", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-20T22:56:20", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-21T05:00:30", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-21T05:00:30", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-21T14:57:12", + "expectedNormal": 5.7, + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-21T17:25:57", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-21T19:55:14", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-21T20:21:02", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-21T20:48:12", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-21T23:36:01", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-22T00:17:02", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-22T07:20:00", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-22T07:20:00", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-22T09:32:51", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-22T15:34:54", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-22T17:17:07", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-22T18:33:33", + "normal": 8.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-22T19:56:36", + "normal": 4.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-22T21:38:22", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-23T14:44:27", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-23T16:39:55", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-23T17:17:36", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-23T18:45:04", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-23T21:54:57", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-23T23:08:34", + "expectedNormal": 2.5, + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-23T23:30:54", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-24T10:55:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-24T16:10:07", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-24T16:10:07", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-24T18:45:06", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-24T18:45:06", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-24T21:29:29", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-25T02:05:38", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-25T16:31:35", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-25T16:52:59", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-25T23:23:29", + "normal": 9.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-25T23:23:29", + "normal": 9.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-26T10:15:03", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-26T13:15:18", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-26T13:53:04", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-26T15:43:54", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-26T20:06:36", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-27T12:42:46", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-27T15:48:19", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-27T15:53:18", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-27T23:14:39", + "normal": 9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-28T02:49:38", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-28T14:15:39", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-28T14:15:39", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-28T15:36:19", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-28T17:22:40", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-28T23:33:46", + "normal": 6.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-29T12:43:56", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-29T14:24:57", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-29T16:00:35", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-29T16:00:35", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-29T22:51:00", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-30T16:41:59", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-30T23:51:20", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-04-30T23:51:20", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-01T00:40:06", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-01T02:19:29", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-01T15:47:28", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-01T17:58:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-01T17:58:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-02T01:01:32", + "duration": 5400000, + "extended": 1.85, + "normal": 0.05, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-02T01:01:32", + "duration": 5400000, + "extended": 1.85, + "normal": 0.05, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-02T14:35:54", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-02T16:30:55", + "normal": 1.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-02T16:30:55", + "normal": 1.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-02T18:03:13", + "normal": 2.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-02T18:03:13", + "normal": 2.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-02T18:30:32", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-02T22:44:03", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-03T13:28:40", + "normal": 7.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-03T13:28:40", + "normal": 7.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-03T22:38:40", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-03T22:38:40", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-04T06:40:11", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-04T12:09:02", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-04T12:42:38", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-04T13:58:04", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-04T19:31:20", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-04T19:31:20", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-05T13:12:58", + "normal": 5.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-05T13:12:58", + "normal": 5.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-05T17:02:00", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-05T17:02:00", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-05T22:18:24", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-05T22:18:24", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-06T12:34:16", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-06T20:28:21", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-06T21:05:28", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-07T10:11:40", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-07T12:47:09", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-07T12:47:09", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-07T20:59:51", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-07T21:46:06", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-08T07:29:03", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-08T07:29:03", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-08T13:44:00", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-08T13:44:00", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-08T20:00:38", + "normal": 2.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-08T20:00:38", + "normal": 2.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-09T14:28:06", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-09T14:28:06", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-09T23:50:14", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-10T10:13:12", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-10T12:28:54", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-10T12:28:54", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-10T14:38:18", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-10T18:48:40", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-10T18:48:40", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-10T19:22:11", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-10T20:10:02", + "normal": 0.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-10T20:10:02", + "normal": 0.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-10T20:43:41", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-11T02:11:06", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-11T15:22:52", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-11T19:51:32", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-11T20:01:17", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-11T21:07:27", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-11T22:40:53", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-12T00:51:28", + "normal": 5.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-12T00:51:28", + "normal": 5.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-12T09:31:50", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-12T17:24:32", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-12T17:31:58", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-12T19:20:54", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-12T20:09:19", + "normal": 6.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-12T23:53:39", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-13T06:04:08", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-13T09:33:30", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-13T09:33:30", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-13T10:02:35", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-13T13:25:22", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-13T14:39:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-13T21:27:31", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-13T21:49:54", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-13T21:49:54", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-14T06:30:45", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-14T17:13:50", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-14T17:13:50", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-14T19:51:30", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-15T02:59:12", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-15T18:34:17", + "normal": 8.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-15T18:34:17", + "normal": 8.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-15T20:03:48", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-15T20:13:10", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-15T21:08:56", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-15T21:38:31", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-16T11:44:10", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-16T13:54:41", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-16T17:33:07", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-16T18:59:52", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-16T22:40:06", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-16T22:40:06", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-17T10:47:43", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-17T17:33:07", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-17T17:33:07", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-17T21:09:30", + "normal": 8.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-17T21:09:30", + "normal": 8.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-17T21:38:23", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-17T21:38:23", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-18T14:40:29", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-18T16:20:15", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-18T17:18:29", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-18T21:04:49", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-18T21:04:49", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-19T08:29:53", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-19T08:29:53", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-19T10:55:07", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-19T13:03:51", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-19T20:15:44", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-19T20:28:37", + "normal": 10.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-19T20:28:37", + "normal": 10.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-20T00:18:39", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-20T01:24:17", + "normal": 0.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-20T01:24:17", + "normal": 0.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-20T07:49:45", + "normal": 0.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-20T07:49:45", + "normal": 0.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-20T11:51:55", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-20T12:13:22", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-20T14:57:44", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-20T18:03:00", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-21T10:31:41", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-21T10:31:41", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-21T13:57:19", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-21T19:23:59", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-21T19:23:59", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-21T22:46:23", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-22T09:51:09", + "normal": 9.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-22T09:51:09", + "normal": 9.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-22T19:41:23", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-22T19:41:23", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-22T22:49:19", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-23T07:43:22", + "normal": 5.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-23T07:43:22", + "normal": 5.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-23T15:05:51", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-23T15:05:51", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-23T16:43:30", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-23T16:43:30", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-23T20:24:21", + "normal": 10.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-23T20:24:21", + "normal": 10.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-23T20:36:41", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-24T01:31:04", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-24T01:31:04", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-24T12:17:15", + "normal": 4.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-24T12:17:15", + "normal": 4.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-24T13:52:54", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-24T22:00:26", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-24T22:31:42", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-24T22:31:42", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-25T07:08:36", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-25T07:08:36", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-25T09:25:26", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-25T09:25:26", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-25T10:43:07", + "duration": 3600000, + "extended": 2.15, + "normal": 6.35, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-25T10:43:07", + "duration": 3600000, + "extended": 2.15, + "normal": 6.35, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-25T15:29:54", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-25T19:28:58", + "normal": 4.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-25T21:48:56", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-26T07:47:05", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-26T15:09:57", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-26T15:23:19", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-26T19:21:32", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-26T19:21:32", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-26T22:54:32", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-27T08:07:50", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-27T08:07:50", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-27T12:47:09", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-27T12:47:09", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-27T13:23:20", + "normal": 1.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-27T13:23:20", + "normal": 1.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-27T17:55:40", + "normal": 7.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-27T19:30:40", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-27T22:57:00", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-28T02:25:19", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-28T16:54:27", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-28T16:54:27", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-28T17:18:04", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-28T19:15:15", + "normal": 6.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-28T20:51:16", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-28T23:10:50", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-29T01:18:06", + "normal": 1.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-29T01:18:06", + "normal": 1.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-29T14:47:42", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-29T16:34:10", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-29T22:26:32", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-31T04:03:49", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-31T10:56:21", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-31T13:27:12", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-31T19:41:58", + "normal": 2.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-31T19:41:58", + "normal": 2.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-31T21:08:12", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-31T21:08:12", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-31T22:40:45", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-05-31T23:11:40", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-01T11:33:30", + "normal": 2.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-01T11:33:30", + "normal": 2.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-01T20:49:42", + "normal": 5.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-01T20:49:42", + "normal": 5.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-01T23:31:41", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-02T02:42:26", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-02T02:42:26", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-02T03:08:32", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-02T12:36:04", + "normal": 7.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-02T12:36:04", + "normal": 7.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-02T13:23:44", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-02T20:07:26", + "normal": 7.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-03T15:01:33", + "normal": 0.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-03T15:46:39", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-03T16:41:33", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-03T17:18:38", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-03T17:43:38", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-04T10:16:53", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-04T14:50:00", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-04T16:14:19", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-04T19:21:41", + "normal": 8.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-04T19:21:41", + "normal": 8.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-04T23:46:41", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-05T00:44:34", + "expectedNormal": 2, + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-05T01:02:58", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-05T12:01:09", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-05T12:01:09", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-05T12:23:18", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-05T12:51:54", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-05T15:39:48", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-05T15:39:48", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-05T21:29:36", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-05T21:29:36", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-06T04:21:34", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-06T04:21:34", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-06T08:53:58", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-06T08:53:58", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-07T15:08:48", + "normal": 0.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-10T19:54:26", + "normal": 7.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-08T15:53:04", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-08T15:53:04", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-08T22:22:31", + "normal": 7.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-08T22:47:20", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-09T15:51:36", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-10T00:59:27", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-10T00:59:27", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-10T10:23:36", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-10T18:30:44", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-10T18:39:41", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-10T18:39:41", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-10T19:47:34", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-11T13:53:18", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-11T20:58:05", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-12T00:35:54", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-12T13:04:51", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-12T17:37:35", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-12T19:09:48", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-12T19:09:48", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-12T19:34:40", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-13T00:02:43", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-13T00:11:41", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-13T00:11:41", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-13T08:33:39", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-13T20:19:52", + "duration": 1800000, + "extended": 2.55, + "normal": 0.6, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-13T20:19:52", + "duration": 1800000, + "extended": 2.55, + "normal": 0.6, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-14T16:44:31", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-14T16:44:31", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-14T22:46:55", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-15T00:28:57", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-15T08:51:33", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-15T11:33:53", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-15T19:09:51", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-16T17:02:11", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-16T17:02:11", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-16T18:49:50", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-16T20:22:02", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-17T11:14:04", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-17T19:29:27", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-18T06:45:25", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-18T15:28:35", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-18T16:20:17", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-18T16:50:44", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-18T22:16:57", + "duration": 3600000, + "extended": 4.2, + "normal": 2.8, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-18T22:16:57", + "duration": 3600000, + "extended": 4.2, + "normal": 2.8, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-19T07:18:23", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-19T18:51:48", + "normal": 4.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-19T18:51:48", + "normal": 4.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-20T08:50:29", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-20T11:19:38", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-20T11:19:38", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-20T15:42:53", + "duration": 1800000, + "extended": 0.45, + "normal": 1.3, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-20T15:42:53", + "duration": 1800000, + "extended": 0.45, + "normal": 1.3, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-20T17:25:24", + "duration": 3600000, + "extended": 0.75, + "normal": 3, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-20T17:25:24", + "duration": 3600000, + "extended": 0.75, + "normal": 3, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-20T21:38:30", + "duration": 3600000, + "extended": 2.85, + "normal": 6.55, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-20T21:38:30", + "duration": 3600000, + "extended": 2.85, + "normal": 6.55, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-21T11:54:08", + "duration": 3600000, + "extended": 2.8, + "normal": 2.8, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-21T14:39:04", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-21T14:39:04", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-21T18:23:31", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-21T19:29:16", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-21T20:00:12", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-21T20:00:12", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-21T21:40:40", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-21T23:42:55", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-22T00:24:30", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-22T08:20:59", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-22T08:20:59", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-22T21:37:44", + "duration": 3600000, + "extended": 1.2, + "normal": 4.8, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-22T21:37:44", + "duration": 3600000, + "extended": 1.2, + "normal": 4.8, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-22T22:25:47", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-22T23:37:05", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-22T23:37:05", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-23T07:32:39", + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-23T07:32:39", + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-23T19:09:07", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-23T20:27:18", + "duration": 3600000, + "extended": 1.75, + "normal": 3.25, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-23T22:28:35", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-23T23:23:04", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T08:19:28", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T08:19:28", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T09:04:06", + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T09:04:06", + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T10:00:56", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T10:00:56", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T18:30:46", + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T18:30:46", + "normal": 4.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T19:44:10", + "normal": 1.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T19:44:10", + "normal": 1.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T20:32:30", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T20:39:38", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-24T20:39:38", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-25T09:17:23", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-25T16:59:11", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-25T16:59:11", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-25T17:49:12", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-25T19:55:43", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-25T19:55:43", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-26T03:01:17", + "normal": 1.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-26T03:01:17", + "normal": 1.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-26T07:05:35", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-26T09:44:50", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-26T09:44:50", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-27T16:48:06", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-27T17:13:45", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-27T17:57:18", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-27T22:06:32", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-27T22:06:32", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-28T15:46:44", + "normal": 6.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-28T15:46:44", + "normal": 6.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-28T16:18:13", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-28T16:23:18", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-28T16:28:41", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-29T18:27:23", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-29T18:27:23", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-30T12:43:51", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-06-30T12:43:51", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-01T17:46:55", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-01T17:46:55", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-01T18:30:32", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-01T18:51:38", + "normal": 4.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-01T18:51:38", + "normal": 4.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-02T00:15:19", + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-02T00:15:19", + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-02T06:49:58", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-02T06:49:58", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-02T18:35:00", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-02T18:35:00", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-03T12:03:51", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-03T12:50:24", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-03T17:08:12", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-03T17:41:00", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-03T17:41:00", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-03T19:08:04", + "expectedNormal": 2, + "normal": 0.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-03T19:08:18", + "normal": 0.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-04T01:21:22", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-04T14:10:31", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-04T14:10:31", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-04T17:59:30", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-04T17:59:30", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-04T19:21:37", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-04T19:21:37", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-04T19:25:51", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-04T20:09:01", + "normal": 7.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-04T20:09:01", + "normal": 7.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-05T02:02:39", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-05T02:02:39", + "normal": 1.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-05T02:36:40", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-05T13:58:30", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-05T13:58:30", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-05T17:17:54", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-05T17:17:54", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-05T23:40:50", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-05T23:40:50", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-06T01:28:33", + "normal": 3.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-06T01:28:33", + "normal": 3.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-06T14:59:11", + "normal": 2.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-06T14:59:11", + "normal": 2.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-06T20:26:50", + "duration": 3600000, + "extended": 2, + "normal": 6, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-06T20:26:50", + "duration": 3600000, + "extended": 2, + "normal": 6, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-07T00:48:50", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-07T14:09:43", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-07T16:02:12", + "duration": 5400000, + "extended": 3.25, + "normal": 9.75, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-08T18:17:26", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-08T18:29:06", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-08T20:29:43", + "normal": 5.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-08T20:29:43", + "normal": 5.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-08T23:53:16", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-08T23:53:16", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-09T12:19:24", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-09T12:19:24", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-09T16:27:30", + "duration": 3600000, + "extended": 1, + "normal": 5.65, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-09T16:27:30", + "duration": 3600000, + "extended": 1, + "normal": 5.65, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-09T17:50:34", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-10T00:25:49", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-10T17:43:21", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-10T18:08:03", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-11T13:06:32", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-11T19:37:52", + "normal": 7.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-11T19:37:52", + "normal": 7.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-12T00:07:01", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-12T00:07:01", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-12T00:42:51", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-12T07:40:06", + "normal": 3.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-12T07:40:06", + "normal": 3.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-12T08:50:10", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-12T16:09:42", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-12T21:45:57", + "normal": 6.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-12T21:45:57", + "normal": 6.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-13T10:56:43", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-13T11:42:47", + "normal": 1.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-13T11:42:47", + "normal": 1.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-13T16:33:50", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-13T18:21:41", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-13T22:13:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-13T22:19:30", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-13T22:48:14", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-13T23:08:30", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-14T14:31:41", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-14T15:53:20", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-14T17:37:39", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-14T18:15:11", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-14T20:29:30", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-15T12:18:56", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-15T14:09:52", + "normal": 4.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-15T14:09:52", + "normal": 4.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-15T17:23:04", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-15T17:23:04", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-15T21:15:01", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-15T21:44:35", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-15T22:12:37", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-15T22:57:20", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-15T22:58:49", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-16T09:35:57", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-16T11:31:07", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-16T15:12:49", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-16T15:41:21", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-16T21:04:38", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-17T03:22:39", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-17T03:22:39", + "normal": 1.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-17T14:09:57", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-17T16:29:43", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-17T16:29:43", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-18T05:26:35", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-18T05:26:35", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-18T08:03:17", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-18T17:58:39", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-18T20:40:22", + "duration": 1800000, + "extended": 5.7, + "normal": 1.9, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-18T20:40:22", + "duration": 1800000, + "extended": 5.7, + "normal": 1.9, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-19T08:36:08", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-19T15:20:39", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-19T18:22:28", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-19T18:54:15", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-19T22:20:06", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-19T22:47:22", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-20T14:23:03", + "duration": 3600000, + "extended": 1.35, + "normal": 5.4, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-20T14:23:03", + "duration": 3600000, + "extended": 1.35, + "normal": 5.4, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-20T15:02:15", + "normal": 3.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-20T15:50:21", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-21T00:08:35", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-21T00:08:35", + "normal": 1.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-21T12:12:24", + "normal": 5.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-21T12:12:24", + "normal": 5.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-21T15:13:53", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-21T15:13:53", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-22T16:11:14", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-23T01:06:51", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-23T01:06:51", + "normal": 2.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-23T10:37:02", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-23T16:18:09", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-23T16:18:09", + "normal": 6.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-23T16:57:31", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-23T21:30:01", + "duration": 1800000, + "extended": 3.55, + "normal": 1.15, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-23T21:30:01", + "duration": 1800000, + "extended": 3.55, + "normal": 1.15, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-24T08:03:19", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-24T13:21:49", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-24T13:41:26", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-24T15:13:42", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-24T17:30:34", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-24T18:47:01", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-25T00:37:32", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-25T15:27:34", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-25T15:50:46", + "normal": 6.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-25T18:34:45", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-25T18:34:45", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-26T08:00:02", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-26T15:30:21", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-26T15:30:21", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-26T16:43:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-26T22:55:06", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-27T00:34:23", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-27T16:08:38", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-28T10:22:34", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-28T10:42:12", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-28T11:14:05", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-28T12:22:02", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-28T12:22:02", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-28T17:58:24", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-29T00:59:10", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-29T13:21:48", + "normal": 3.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-29T13:21:48", + "normal": 3.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-29T14:26:37", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-29T14:26:37", + "normal": 5.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-29T15:29:23", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-29T19:11:00", + "normal": 3.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-29T21:59:18", + "duration": 10800000, + "extended": 8.65, + "normal": 2.85, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-29T21:59:18", + "duration": 10800000, + "extended": 8.65, + "normal": 2.85, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-30T07:29:04", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-30T11:32:41", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-30T11:32:41", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-30T13:33:42", + "normal": 2.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-30T13:33:42", + "normal": 2.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-30T15:10:57", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-30T16:48:04", + "duration": 2700000, + "expectedDuration": 3600000, + "expectedExtended": 2.65, + "extended": 1.95, + "normal": 4.5, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-30T16:48:04", + "duration": 2700000, + "expectedDuration": 3600000, + "expectedExtended": 2.65, + "extended": 1.95, + "normal": 4.5, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-30T17:35:25", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-31T06:01:14", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-31T08:02:24", + "expectedNormal": 1.8, + "normal": 0, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-31T17:32:27", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-31T17:32:27", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-31T19:24:54", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-31T20:15:14", + "normal": 7.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-31T20:15:14", + "normal": 7.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-07-31T23:11:02", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-01T15:38:03", + "normal": 7.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-02T00:53:24", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-02T00:53:24", + "normal": 1.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-02T09:42:56", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-02T12:33:40", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-03T13:13:56", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-03T13:13:56", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-03T13:30:33", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-03T19:02:46", + "normal": 7.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-03T19:02:46", + "normal": 7.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-03T23:23:36", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-03T23:30:48", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-04T07:57:10", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-04T17:05:51", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-04T18:14:03", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-05T16:45:27", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-05T19:47:08", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-06T09:25:42", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-06T15:20:44", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-06T16:19:31", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-06T17:07:49", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-06T19:58:23", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-06T19:58:23", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-07T14:38:43", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-07T19:47:20", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-07T20:51:30", + "normal": 8.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-07T20:51:30", + "normal": 8.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-07T21:31:38", + "normal": 5.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-07T21:31:38", + "normal": 5.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-08T01:05:38", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-08T10:11:09", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-08T15:43:17", + "normal": 6.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-08T15:43:17", + "normal": 6.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-08T19:52:56", + "normal": 0.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-08T20:57:40", + "duration": 3600000, + "extended": 2, + "normal": 8.95, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-08T20:57:40", + "duration": 3600000, + "extended": 2, + "normal": 8.95, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-09T09:07:47", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-09T16:17:45", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-09T17:24:45", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-11T01:12:55", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-11T18:24:34", + "normal": 5.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-11T18:24:34", + "normal": 5.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-11T19:04:48", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-11T20:30:46", + "normal": 0.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-11T20:30:46", + "normal": 0.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-12T10:04:06", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-13T17:30:51", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-13T18:15:01", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-13T18:15:01", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-13T18:43:29", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-14T15:37:44", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-15T01:47:54", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-15T13:59:56", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-15T14:41:43", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-15T14:44:38", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-15T21:54:18", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-16T15:51:57", + "normal": 7.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-16T15:51:57", + "normal": 7.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-16T16:23:22", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-16T20:59:44", + "normal": 7.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-16T20:59:44", + "normal": 7.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-16T22:28:09", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-17T13:43:39", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-17T15:22:58", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-17T20:43:00", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-17T20:43:00", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-17T22:37:07", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-17T22:37:07", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-18T12:51:55", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-18T15:37:39", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-18T15:37:39", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-18T16:20:47", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-18T16:23:34", + "expectedNormal": 1, + "normal": 0, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-18T16:23:47", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-19T01:18:52", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-19T18:35:04", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-19T18:35:04", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-19T18:45:16", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-19T19:19:18", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-19T19:49:49", + "normal": 9.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-20T13:23:57", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-20T13:23:57", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-20T18:56:03", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-20T18:56:03", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-21T18:29:04", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-21T18:29:04", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-21T20:46:21", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-21T20:46:21", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-22T21:10:05", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-22T21:58:04", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-22T22:02:55", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-23T18:27:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-23T18:27:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-23T20:31:41", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-23T20:59:54", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-23T23:21:11", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-24T10:24:29", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-24T17:07:32", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-24T17:33:08", + "normal": 0.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-24T18:35:51", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-25T14:07:13", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-25T17:12:17", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-25T21:24:58", + "normal": 8.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-26T11:35:34", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-26T11:48:12", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-26T12:08:19", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-26T16:13:11", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-26T22:12:41", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-27T01:27:13", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-27T16:56:37", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-27T19:56:41", + "normal": 1.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-27T20:22:28", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-27T20:57:07", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-28T07:42:06", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-28T07:42:06", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-28T09:05:30", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-28T09:05:30", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-28T09:54:05", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-28T09:54:05", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-28T14:01:25", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-28T15:50:43", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-28T20:59:49", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-28T21:29:58", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-29T01:28:07", + "expectedNormal": 3, + "normal": 0, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-29T01:28:23", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-29T05:09:40", + "expectedNormal": 2.55, + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-29T05:09:40", + "expectedNormal": 2.55, + "normal": 1.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-29T05:18:26", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-29T05:18:26", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-29T06:58:48", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-29T07:02:43", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-29T13:23:14", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-29T21:18:42", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-29T21:18:42", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-30T15:27:04", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-30T15:45:46", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-30T16:03:48", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-30T21:27:24", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-31T00:32:49", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-31T00:32:49", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-08-31T14:12:55", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-01T00:10:43", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-01T00:20:00", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-01T01:11:31", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-01T18:11:06", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-01T18:59:49", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-01T18:59:49", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-01T23:21:40", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T01:17:05", + "normal": 2.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T07:22:03", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T09:19:07", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T15:32:12", + "duration": 3600000, + "extended": 1.65, + "normal": 3.8, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T15:32:12", + "duration": 3600000, + "extended": 1.65, + "normal": 3.8, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T17:09:29", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T19:39:58", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T19:39:58", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T20:38:24", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T20:38:24", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T20:44:02", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-02T21:40:20", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-03T00:20:40", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-03T00:20:40", + "normal": 3.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-03T06:42:57", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-03T14:08:27", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-03T14:48:55", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-03T17:14:46", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-03T22:34:31", + "normal": 5.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-04T00:28:34", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-04T06:09:22", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-04T14:45:39", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-04T18:24:53", + "normal": 10.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-05T01:06:54", + "normal": 6.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-05T16:22:33", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-05T16:58:48", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-05T21:45:50", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-06T00:55:25", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-06T15:41:42", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-06T15:45:31", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-06T16:47:53", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-06T21:15:40", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-06T21:15:40", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-07T19:12:03", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-07T19:57:42", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-07T20:27:57", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-07T23:09:54", + "normal": 10.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-08T06:49:54", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-08T13:38:14", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-08T19:03:48", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-08T21:12:03", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-08T22:21:55", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-09T01:19:46", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-09T15:05:45", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-09T22:54:59", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-09T23:26:51", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-10T16:45:44", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-10T17:22:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-10T20:02:24", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-10T22:48:01", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-10T23:18:10", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-11T17:11:53", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-11T23:15:24", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-12T00:04:13", + "normal": 2.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-12T00:04:13", + "normal": 2.25, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-12T00:28:22", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-12T15:21:56", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-13T15:59:02", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-13T22:06:29", + "normal": 6.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-14T11:11:32", + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-14T13:09:35", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-14T19:24:39", + "normal": 10.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-14T19:24:39", + "normal": 10.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-15T15:36:19", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-15T21:46:47", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-15T21:46:47", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-15T22:10:16", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-16T15:44:33", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-16T21:36:53", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-17T15:59:12", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-17T16:08:56", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-17T21:09:25", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-17T21:09:25", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-18T09:37:49", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-18T18:20:54", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-18T18:51:09", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-19T13:27:26", + "duration": 3600000, + "extended": 0.55, + "normal": 0.25, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-19T13:27:26", + "duration": 3600000, + "extended": 0.55, + "normal": 0.25, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-19T14:53:40", + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-19T14:53:40", + "normal": 4.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-19T15:24:30", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-20T18:32:41", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-20T21:29:36", + "normal": 5.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-21T15:35:49", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-21T15:35:49", + "normal": 5.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-21T21:03:52", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-21T22:39:49", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-22T11:25:56", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-22T13:19:40", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-22T17:25:35", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-22T19:59:31", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-22T22:50:19", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-23T11:45:40", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-23T11:47:49", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-23T12:07:32", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-23T15:08:45", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-23T20:33:01", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-23T22:00:40", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-24T06:08:59", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-24T08:33:59", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-24T11:22:33", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-24T21:52:26", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-24T22:08:46", + "normal": 7.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-25T16:52:46", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-25T20:23:33", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-25T20:36:44", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-26T07:18:20", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-26T10:15:04", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-26T16:11:43", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-26T19:25:09", + "normal": 6.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-26T21:22:26", + "normal": 1.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-26T21:22:26", + "normal": 1.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-27T12:14:07", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-27T13:57:02", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-27T14:09:20", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-27T15:29:54", + "normal": 2.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-27T20:48:41", + "normal": 2.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-27T21:12:09", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-27T21:20:49", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-27T21:49:25", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-28T04:50:11", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-28T07:40:45", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-28T12:06:19", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-28T15:46:19", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-28T15:46:19", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-28T21:47:01", + "normal": 12.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-28T21:47:01", + "normal": 12.35, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-29T01:12:35", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-29T02:08:17", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-29T02:59:26", + "normal": 0.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-29T14:42:33", + "normal": 7.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-29T14:42:33", + "normal": 7.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-29T15:02:43", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-29T15:12:10", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-29T19:10:18", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-29T19:46:49", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-30T11:29:40", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-30T13:56:15", + "normal": 5.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-30T15:42:59", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-30T22:53:22", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-30T23:05:22", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-09-30T23:35:16", + "normal": 7.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-01T14:27:43", + "normal": 1.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-01T16:04:42", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-01T22:28:45", + "normal": 6.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-01T22:28:45", + "normal": 6.85, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-02T17:01:12", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-02T17:01:12", + "normal": 0.7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-02T18:18:32", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-02T22:08:17", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-02T22:56:37", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-03T07:44:00", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-03T08:42:58", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-03T15:24:28", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-03T15:24:28", + "normal": 3.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-03T17:53:59", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-03T17:53:59", + "normal": 0.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-03T19:00:37", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-03T22:17:33", + "normal": 7.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-03T22:17:33", + "normal": 7.65, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-04T09:52:11", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-04T12:55:58", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-04T12:55:58", + "normal": 2.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-04T15:12:11", + "normal": 6.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-04T20:09:22", + "normal": 3.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-05T03:27:19", + "normal": 4.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-05T03:27:19", + "normal": 4.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-05T19:22:47", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-05T19:22:47", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-05T22:39:45", + "normal": 10.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-05T22:39:45", + "normal": 10.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-06T06:12:37", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-06T06:12:37", + "normal": 4.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-06T12:42:06", + "normal": 8.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-06T15:32:00", + "expectedNormal": 4.7, + "normal": 2.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-06T19:07:20", + "normal": 4.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-06T19:39:58", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-07T00:20:47", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-07T05:30:49", + "normal": 2.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-07T08:21:15", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-07T22:44:14", + "normal": 8.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-08T06:58:25", + "normal": 4.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-08T08:16:59", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-08T13:52:10", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-08T19:52:08", + "normal": 5.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-08T19:52:08", + "normal": 5.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-09T06:26:22", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-09T06:26:22", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-09T07:43:04", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-09T15:08:46", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-09T15:54:44", + "normal": 3.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-09T23:03:47", + "normal": 4.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-09T23:38:04", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-09T23:38:04", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-10T16:02:43", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-10T22:56:35", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-10T22:56:35", + "normal": 3.45, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-10T23:35:59", + "normal": 2.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-11T15:03:25", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-11T15:03:25", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-11T16:13:04", + "normal": 2.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-11T21:19:03", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-11T21:19:03", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-12T07:22:58", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-12T15:16:54", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-12T15:16:54", + "normal": 3.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-12T15:54:25", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-12T21:11:04", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-12T21:11:04", + "normal": 4.05, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-13T13:15:55", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-13T13:18:43", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-13T13:18:43", + "normal": 5.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-13T16:26:19", + "normal": 6.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-13T16:26:19", + "normal": 6.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-13T20:33:47", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-13T20:33:47", + "normal": 8.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-13T20:49:06", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-13T21:24:48", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-13T23:18:40", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-13T23:45:17", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-14T00:25:53", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-14T01:10:52", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-14T12:00:00", + "normal": 3.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-14T15:36:08", + "normal": 1.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-14T16:01:10", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-14T19:58:59", + "normal": 3.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-14T20:51:48", + "normal": 8.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-14T20:51:48", + "normal": 8.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-14T21:40:26", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-14T23:14:13", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-15T00:33:52", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-15T00:33:52", + "normal": 3.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-15T08:45:17", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-15T15:49:05", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-15T21:53:25", + "normal": 8.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-15T21:53:25", + "normal": 8.75, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-15T22:38:18", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-16T16:47:33", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-16T22:22:47", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-16T23:27:48", + "normal": 14.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-17T15:50:12", + "normal": 3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-17T15:52:31", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-18T14:12:19", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-18T15:09:54", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-18T15:27:12", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-18T15:57:46", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-18T23:28:05", + "normal": 8.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-18T23:28:05", + "normal": 8.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-19T00:10:14", + "normal": 5.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-19T00:46:24", + "normal": 5.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-19T01:11:02", + "normal": 5.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-19T14:59:14", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-19T16:28:00", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-19T22:00:22", + "normal": 6.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-19T23:24:34", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-20T17:39:33", + "normal": 4.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-20T19:27:43", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-20T20:07:49", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-20T20:43:12", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-20T21:54:33", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-21T14:16:42", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-21T20:42:35", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-22T12:14:12", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-23T07:12:15", + "normal": 3.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-23T11:12:32", + "normal": 1.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-23T12:36:16", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-23T12:50:53", + "normal": 8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-23T14:17:09", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-24T10:47:06", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-24T14:20:06", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-24T16:11:40", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-25T00:18:43", + "normal": 0.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-25T19:12:42", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-25T19:12:42", + "normal": 3.95, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-25T20:42:26", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-25T20:42:26", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-26T18:49:01", + "normal": 4.6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-27T18:11:11", + "normal": 2.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-27T20:47:51", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-28T13:28:57", + "normal": 1.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-28T13:31:35", + "normal": 5.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-28T13:43:39", + "normal": 1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-28T18:08:08", + "normal": 2.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-29T03:56:45", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-29T03:56:45", + "normal": 4.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-29T15:09:37", + "normal": 5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-29T15:58:27", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-29T15:58:27", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-30T02:57:09", + "normal": 4.8, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-30T16:34:05", + "normal": 10, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-30T19:17:07", + "expectedNormal": 8, + "normal": 6.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-30T23:28:05", + "normal": 1.3, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-10-31T20:19:12", + "normal": 6, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-01T16:10:05", + "normal": 7, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-01T23:01:05", + "normal": 3.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-01T23:01:05", + "normal": 3.15, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-02T17:16:10", + "normal": 4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-02T23:46:20", + "normal": 8.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-03T12:56:37", + "normal": 6.1, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-03T13:09:30", + "normal": 7.4, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-03T16:07:02", + "normal": 1.5, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-03T20:10:25", + "duration": 3600000, + "extended": 2.2, + "normal": 12.3, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-03T20:10:25", + "duration": 3600000, + "extended": 2.2, + "normal": 12.3, + "subType": "dual/square", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-04T05:00:38", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-04T05:00:38", + "normal": 3.55, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-04T12:35:17", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-04T12:35:17", + "normal": 1.9, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-04T15:46:38", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-04T15:46:38", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-04T22:01:14", + "normal": 4.2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-05T09:37:58", + "normal": 2, + "subType": "normal", + }, + { + "deviceId": "some-other-pump", + "deviceTime": "2018-11-05T13:19:18", + "normal": 2, + "subType": "normal", + }, +} + +var jfBasalStr = `[ + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T22:00:00", + "duration": 1217000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T22:20:17", + "duration": 800000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T22:33:37", + "duration": 5183000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T00:00:00", + "duration": 7992000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T02:13:12", + "duration": 2334000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T05:52:06", + "duration": 6987000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T07:48:33", + "duration": 1140000, + "percent": 0.4, + "rate": 0.62, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T07:48:33", + "duration": 1140000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-11-15T12:49:31Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T07:48:33", + "duration": 1109000, + "expectedDuration": 1140000, + "percent": 0.4, + "rate": 0.62, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T07:48:33", + "duration": 1140000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-11-15T12:49:31Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T08:07:02", + "duration": 2631000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T08:50:53", + "duration": 8779000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:17:12", + "duration": 1800000, + "percent": 0.6, + "rate": 0.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:17:12", + "duration": 1800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-15T16:18:10Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:47:12", + "duration": 592000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:57:04", + "duration": 7200000, + "percent": 0.35, + "rate": 0.5, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:57:04", + "duration": 7200000, + "rate": 1.43, + "scheduleName": "basal 3", + "time": "2017-11-15T16:58:02Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:57:04", + "duration": 176000, + "expectedDuration": 7200000, + "percent": 0.35, + "rate": 0.5, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:57:04", + "duration": 7200000, + "rate": 1.43, + "scheduleName": "basal 3", + "time": "2017-11-15T16:58:02Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T12:00:00", + "duration": 7200000, + "percent": 0.35, + "rate": 0.22, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T12:00:00", + "duration": 7200000, + "rate": 0.63, + "scheduleName": "basal 3", + "time": "2017-11-15T17:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T12:00:00", + "duration": 7024000, + "expectedDuration": 7200000, + "percent": 0.35, + "rate": 0.22, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T12:00:00", + "duration": 7200000, + "rate": 0.63, + "scheduleName": "basal 3", + "time": "2017-11-15T17:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T13:57:04", + "duration": 14576000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T08:30:00", + "duration": 3356000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T09:25:56", + "duration": 7200000, + "percent": 0.5, + "rate": 0.72, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T09:25:56", + "duration": 7200000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2017-11-16T14:26:54Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T11:25:56", + "duration": 2044000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T12:00:00", + "duration": 1425000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T12:23:45", + "duration": 5400000, + "percent": 0.5, + "rate": 0.32, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T12:23:45", + "duration": 5400000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2017-11-16T17:24:43Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T13:53:45", + "duration": 14775000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T00:00:00", + "duration": 2543000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T00:42:23", + "duration": 12600000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T00:42:23", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-17T05:43:21Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T00:42:23", + "duration": 10057000, + "expectedDuration": 12600000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T00:42:23", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-17T05:43:21Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T03:30:00", + "duration": 12600000, + "percent": 0.65, + "rate": 0.84, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T03:30:00", + "duration": 12600000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2017-11-17T08:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T03:30:00", + "duration": 2543000, + "expectedDuration": 12600000, + "percent": 0.65, + "rate": 0.84, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T03:30:00", + "duration": 12600000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2017-11-17T08:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T04:12:23", + "duration": 4657000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T08:30:00", + "duration": 10937000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T11:32:17", + "duration": 10800000, + "percent": 0.6, + "rate": 0.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T11:32:17", + "duration": 10800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-17T16:33:15Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T11:32:17", + "duration": 1663000, + "expectedDuration": 10800000, + "percent": 0.6, + "rate": 0.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T11:32:17", + "duration": 10800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-17T16:33:15Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T12:00:00", + "duration": 7860000, + "percent": 0.6, + "rate": 0.39, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T12:00:00", + "duration": 7860000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-11-17T17:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T12:00:00", + "duration": 6157000, + "expectedDuration": 7860000, + "percent": 0.6, + "rate": 0.39, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T12:00:00", + "duration": 7860000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-11-17T17:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T13:42:37", + "duration": 47000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T13:43:24", + "duration": 10800000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T13:43:24", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-11-17T18:44:22Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T16:43:24", + "duration": 4596000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T18:00:00", + "duration": 2896000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T18:48:16", + "duration": 4862000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T20:09:18", + "duration": 6642000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T00:00:00", + "duration": 10582000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T02:56:22", + "duration": 21600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T02:56:22", + "duration": 21600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-20T07:57:20Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T02:56:22", + "duration": 2018000, + "expectedDuration": 21600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T02:56:22", + "duration": 21600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-20T07:57:20Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T03:30:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T03:30:00", + "duration": 21600000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-11-20T08:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T03:30:00", + "duration": 7200000, + "expectedDuration": 21600000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T03:30:00", + "duration": 21600000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-11-20T08:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T05:30:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T05:30:00", + "duration": 21600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-11-20T10:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T05:30:00", + "duration": 10800000, + "expectedDuration": 21600000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T05:30:00", + "duration": 21600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-11-20T10:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T08:30:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T08:30:00", + "duration": 21600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-20T13:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T08:30:00", + "duration": 1582000, + "expectedDuration": 21600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T08:30:00", + "duration": 21600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-20T13:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T08:56:22", + "duration": 11018000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T12:00:00", + "duration": 7848000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T14:10:48", + "duration": 9000000, + "percent": 1.25, + "rate": 0.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T14:10:48", + "duration": 9000000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-11-20T19:11:46Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T16:40:48", + "duration": 4752000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T18:00:00", + "duration": 4786000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T19:19:46", + "duration": 492000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T19:27:58", + "duration": 9122000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T08:30:00", + "duration": 5770000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:06:10", + "duration": 1860000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:06:10", + "duration": 1860000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-22T15:07:08Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:06:10", + "duration": 1803000, + "expectedDuration": 1860000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:06:10", + "duration": 1860000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-22T15:07:08Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:36:13", + "duration": 13000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:36:26", + "duration": 3600000, + "percent": 1.15, + "rate": 1.66, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:36:26", + "duration": 3600000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2017-11-22T15:37:24Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T11:36:26", + "duration": 1414000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T12:00:00", + "duration": 19357000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T17:22:37", + "duration": 385000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T17:29:02", + "duration": 1858000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T12:00:00", + "duration": 499000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T12:08:19", + "duration": 9000000, + "percent": 0.55, + "rate": 0.35, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T12:08:19", + "duration": 9000000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2017-11-23T17:09:17Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T14:38:19", + "duration": 8117000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T16:53:36", + "duration": 5400000, + "percent": 1.5, + "rate": 0.97, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T16:53:36", + "duration": 5400000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-11-23T21:54:34Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T16:53:36", + "duration": 3984000, + "expectedDuration": 5400000, + "percent": 1.5, + "rate": 0.97, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T16:53:36", + "duration": 5400000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-11-23T21:54:34Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T18:00:00", + "duration": 5400000, + "percent": 1.5, + "rate": 1.72, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T18:00:00", + "duration": 5400000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2017-11-23T23:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T18:00:00", + "duration": 1416000, + "expectedDuration": 5400000, + "percent": 1.5, + "rate": 1.72, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T18:00:00", + "duration": 5400000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2017-11-23T23:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T18:23:36", + "duration": 12984000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T22:00:00", + "duration": 1335000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T22:22:15", + "duration": 7200000, + "percent": 0.7, + "rate": 0.91, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T22:22:15", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-11-24T03:23:13Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T22:22:15", + "duration": 5865000, + "expectedDuration": 7200000, + "percent": 0.7, + "rate": 0.91, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T22:22:15", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-11-24T03:23:13Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T00:00:00", + "duration": 7200000, + "percent": 0.7, + "rate": 1.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T00:00:00", + "duration": 7200000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2017-11-24T05:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T00:00:00", + "duration": 1335000, + "expectedDuration": 7200000, + "percent": 0.7, + "rate": 1.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T00:00:00", + "duration": 7200000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2017-11-24T05:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T00:22:15", + "duration": 5651000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T01:56:26", + "duration": 16200000, + "percent": 0.5, + "rate": 0.72, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T01:56:26", + "duration": 16200000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2017-11-24T06:57:24Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T01:56:26", + "duration": 5614000, + "expectedDuration": 16200000, + "percent": 0.5, + "rate": 0.72, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T01:56:26", + "duration": 16200000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2017-11-24T06:57:24Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:30:00", + "duration": 6360000, + "percent": 0.5, + "rate": 0.65, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:30:00", + "duration": 6360000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-11-24T08:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:30:00", + "duration": 713000, + "expectedDuration": 6360000, + "percent": 0.5, + "rate": 0.65, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:30:00", + "duration": 6360000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-11-24T08:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:41:53", + "duration": 14000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:42:07", + "duration": 480000, + "percent": 0.15000000000000002, + "rate": 0.19, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:42:07", + "duration": 480000, + "rate": 1.27, + "scheduleName": "basal 3", + "time": "2017-11-24T08:43:05Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:42:07", + "duration": 453000, + "expectedDuration": 480000, + "percent": 0.15000000000000002, + "rate": 0.19, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:42:07", + "duration": 480000, + "rate": 1.27, + "scheduleName": "basal 3", + "time": "2017-11-24T08:43:05Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:49:40", + "duration": 21000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:50:01", + "duration": 1260000, + "rate": 0 + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:50:01", + "duration": 1243000, + "expectedDuration": 1260000, + "rate": 0 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T04:10:44", + "duration": 17000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T04:11:01", + "duration": 25200000, + "percent": 0.30000000000000004, + "rate": 0.39, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T04:11:01", + "duration": 25200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-11-24T09:11:59Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T04:11:01", + "duration": 4739000, + "expectedDuration": 25200000, + "percent": 0.30000000000000004, + "rate": 0.39, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T04:11:01", + "duration": 25200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-11-24T09:11:59Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T05:30:00", + "duration": 25200000, + "percent": 0.30000000000000004, + "rate": 0.46, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T05:30:00", + "duration": 25200000, + "rate": 1.53, + "scheduleName": "basal 3", + "time": "2017-11-24T10:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T05:30:00", + "duration": 10800000, + "expectedDuration": 25200000, + "percent": 0.30000000000000004, + "rate": 0.46, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T05:30:00", + "duration": 25200000, + "rate": 1.53, + "scheduleName": "basal 3", + "time": "2017-11-24T10:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T08:30:00", + "duration": 21000000, + "percent": 0.30000000000000004, + "rate": 0.43, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T08:30:00", + "duration": 21000000, + "rate": 1.43, + "scheduleName": "basal 3", + "time": "2017-11-24T13:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T08:30:00", + "duration": 5443000, + "expectedDuration": 21000000, + "percent": 0.30000000000000004, + "rate": 0.43, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T08:30:00", + "duration": 21000000, + "rate": 1.43, + "scheduleName": "basal 3", + "time": "2017-11-24T13:30:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T10:00:43", + "duration": 7157000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T08:30:00", + "duration": 7831000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T10:40:31", + "duration": 3660000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T10:40:31", + "duration": 3660000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-25T15:41:29Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T10:40:31", + "duration": 3630000, + "expectedDuration": 3660000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T10:40:31", + "duration": 3660000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-25T15:41:29Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T11:41:01", + "duration": 26048000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T18:55:09", + "duration": 11091000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T08:30:00", + "duration": 4143000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T09:39:03", + "duration": 5400000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T09:39:03", + "duration": 5400000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-11-26T14:40:01Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T11:09:03", + "duration": 3057000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T12:00:00", + "duration": 11173000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T15:06:13", + "duration": 10800000, + "percent": 0.5, + "rate": 0.32, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T15:06:13", + "duration": 10800000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2017-11-27T20:07:11Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T15:06:13", + "duration": 10427000, + "expectedDuration": 10800000, + "percent": 0.5, + "rate": 0.32, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T15:06:13", + "duration": 10800000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2017-11-27T20:07:11Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T18:00:00", + "duration": 10800000, + "percent": 0.5, + "rate": 0.57, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T18:00:00", + "duration": 10800000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2017-11-27T23:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T18:00:00", + "duration": 373000, + "expectedDuration": 10800000, + "percent": 0.5, + "rate": 0.57, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T18:00:00", + "duration": 10800000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2017-11-27T23:00:58Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T18:06:13", + "duration": 14027000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T05:30:00", + "duration": 7330000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T07:32:10", + "duration": 8320000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T09:50:50", + "duration": 7750000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T12:00:00", + "duration": 13768000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T15:49:28", + "duration": 1919000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T13:21:27", + "duration": 16713000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T18:00:00", + "duration": 7752000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T20:09:12", + "duration": 4951000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T21:31:43", + "duration": 1697000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T05:30:00", + "duration": 2075000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T06:04:35", + "duration": 5400000, + "percent": 1.4, + "rate": 2.17, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T06:04:35", + "duration": 5400000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-12-01T14:05:33Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T07:34:35", + "duration": 3325000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T08:30:00", + "duration": 6166000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T10:12:46", + "duration": 5400000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T10:12:46", + "duration": 5400000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-01T18:13:44Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T11:42:46", + "duration": 1034000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T22:00:00", + "duration": 4345000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T23:12:25", + "duration": 1767000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T23:41:52", + "duration": 1088000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T05:30:00", + "duration": 7632000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T07:37:12", + "duration": 7359000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T09:39:51", + "duration": 8409000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T08:30:00", + "duration": 7692000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T10:38:12", + "duration": 1864000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T11:09:16", + "duration": 3044000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T18:00:00", + "duration": 11017000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T21:03:37", + "duration": 10800000, + "percent": 1.5, + "rate": 1.72, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T21:03:37", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2017-12-13T05:04:35Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T21:03:37", + "duration": 3383000, + "expectedDuration": 10800000, + "percent": 1.5, + "rate": 1.72, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T21:03:37", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2017-12-13T05:04:35Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T22:00:00", + "duration": 10800000, + "percent": 1.5, + "rate": 1.95, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T22:00:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-13T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T22:00:00", + "duration": 7200000, + "expectedDuration": 10800000, + "percent": 1.5, + "rate": 1.95, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T22:00:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-13T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T00:00:00", + "duration": 10800000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T00:00:00", + "duration": 10800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-13T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T00:00:00", + "duration": 217000, + "expectedDuration": 10800000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T00:00:00", + "duration": 10800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-13T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T00:03:37", + "duration": 12383000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T05:30:00", + "duration": 5676000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T07:04:36", + "duration": 7200000, + "percent": 0.4, + "rate": 0.62, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T07:04:36", + "duration": 7200000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-12-13T15:05:34Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T07:04:36", + "duration": 5124000, + "expectedDuration": 7200000, + "percent": 0.4, + "rate": 0.62, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T07:04:36", + "duration": 7200000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-12-13T15:05:34Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T08:30:00", + "duration": 7200000, + "percent": 0.4, + "rate": 0.58, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T08:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-13T16:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T08:30:00", + "duration": 2076000, + "expectedDuration": 7200000, + "percent": 0.4, + "rate": 0.58, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T08:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-13T16:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T09:04:36", + "duration": 8062000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T11:18:58", + "duration": 3600000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T11:18:58", + "duration": 3600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-13T19:19:56Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T11:18:58", + "duration": 2462000, + "expectedDuration": 3600000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T11:18:58", + "duration": 3600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-13T19:19:56Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T12:00:00", + "duration": 3600000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T12:00:00", + "duration": 3600000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-12-13T20:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T12:00:00", + "duration": 1138000, + "expectedDuration": 3600000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T12:00:00", + "duration": 3600000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-12-13T20:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T12:18:58", + "duration": 20462000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T18:00:00", + "duration": 3789000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T19:03:09", + "duration": 4406000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T20:16:35", + "duration": 6205000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T12:00:00", + "duration": 21479000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T17:57:59", + "duration": 7200000, + "percent": 1.45, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T17:57:59", + "duration": 7200000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-12-16T01:58:57Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T17:57:59", + "duration": 121000, + "expectedDuration": 7200000, + "percent": 1.45, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T17:57:59", + "duration": 7200000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2017-12-16T01:58:57Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T18:00:00", + "duration": 7200000, + "percent": 1.45, + "rate": 1.66, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T18:00:00", + "duration": 7200000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2017-12-16T02:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T18:00:00", + "duration": 7079000, + "expectedDuration": 7200000, + "percent": 1.45, + "rate": 1.66, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T18:00:00", + "duration": 7200000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2017-12-16T02:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T19:57:59", + "duration": 7321000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T03:30:00", + "duration": 6942000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:25:42", + "duration": 5400000, + "percent": 1.5, + "rate": 1.95, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:25:42", + "duration": 5400000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-16T13:26:40Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:25:42", + "duration": 258000, + "expectedDuration": 5400000, + "percent": 1.5, + "rate": 1.95, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:25:42", + "duration": 5400000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-16T13:26:40Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:30:00", + "duration": 5400000, + "percent": 1.5, + "rate": 2.32, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:30:00", + "duration": 5400000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-12-16T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:30:00", + "duration": 5142000, + "expectedDuration": 5400000, + "percent": 1.5, + "rate": 2.32, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:30:00", + "duration": 5400000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-12-16T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T06:55:42", + "duration": 5658000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T18:00:00", + "duration": 12497000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T21:28:17", + "duration": 2135000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T22:03:52", + "duration": 6968000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T00:00:00", + "duration": 4032000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T01:07:12", + "duration": 7200000, + "percent": 1.75, + "rate": 2.53, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T01:07:12", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-17T09:08:10Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T03:07:12", + "duration": 1368000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T22:00:00", + "duration": 4835000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T23:20:35", + "duration": 5400000, + "percent": 1.5, + "rate": 1.95, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T23:20:35", + "duration": 5400000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-19T07:21:33Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T23:20:35", + "duration": 2365000, + "expectedDuration": 5400000, + "percent": 1.5, + "rate": 1.95, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T23:20:35", + "duration": 5400000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-19T07:21:33Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T00:00:00", + "duration": 5400000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T00:00:00", + "duration": 5400000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-19T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T00:00:00", + "duration": 3035000, + "expectedDuration": 5400000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T00:00:00", + "duration": 5400000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-19T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T00:50:35", + "duration": 9565000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T05:30:00", + "duration": 1701000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T05:58:21", + "duration": 50296000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T19:56:37", + "duration": 7403000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T18:00:00", + "duration": 8649000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T20:24:09", + "duration": 9000000, + "percent": 1.95, + "rate": 2.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T20:24:09", + "duration": 9000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2017-12-23T04:25:07Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T20:24:09", + "duration": 5751000, + "expectedDuration": 9000000, + "percent": 1.95, + "rate": 2.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T20:24:09", + "duration": 9000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2017-12-23T04:25:07Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T22:00:00", + "duration": 9000000, + "percent": 1.95, + "rate": 2.53, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T22:00:00", + "duration": 9000000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-23T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T22:00:00", + "duration": 3249000, + "expectedDuration": 9000000, + "percent": 1.95, + "rate": 2.53, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T22:00:00", + "duration": 9000000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-23T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T22:54:09", + "duration": 3951000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T18:00:00", + "duration": 366000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T18:06:06", + "duration": 613000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T18:16:19", + "duration": 13421000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T03:30:00", + "duration": 5480000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:01:20", + "duration": 12600000, + "percent": 1.6, + "rate": 2.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:01:20", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-25T13:02:18Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:01:20", + "duration": 1720000, + "expectedDuration": 12600000, + "percent": 1.6, + "rate": 2.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:01:20", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-25T13:02:18Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:30:00", + "duration": 12600000, + "percent": 1.6, + "rate": 2.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:30:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-12-25T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:30:00", + "duration": 10800000, + "expectedDuration": 12600000, + "percent": 1.6, + "rate": 2.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:30:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-12-25T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T08:30:00", + "duration": 12600000, + "percent": 1.6, + "rate": 2.32, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-25T16:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T08:30:00", + "duration": 80000, + "expectedDuration": 12600000, + "percent": 1.6, + "rate": 2.32, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-25T16:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T08:31:20", + "duration": 12520000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T05:30:00", + "duration": 3692000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T06:31:32", + "duration": 14400000, + "percent": 1.65, + "rate": 2.55, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T06:31:32", + "duration": 14400000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-12-26T14:32:30Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T06:31:32", + "duration": 7108000, + "expectedDuration": 14400000, + "percent": 1.65, + "rate": 2.55, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T06:31:32", + "duration": 14400000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2017-12-26T14:32:30Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T08:30:00", + "duration": 14400000, + "percent": 1.65, + "rate": 2.39, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T08:30:00", + "duration": 14400000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-26T16:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T08:30:00", + "duration": 7292000, + "expectedDuration": 14400000, + "percent": 1.65, + "rate": 2.39, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T08:30:00", + "duration": 14400000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-26T16:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T10:31:32", + "duration": 5308000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T18:00:00", + "duration": 9007000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T20:30:07", + "duration": 4826000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T21:50:33", + "duration": 567000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T12:00:00", + "duration": 175000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T12:02:55", + "duration": 203000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T12:06:18", + "duration": 21222000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T22:00:00", + "duration": 5252000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T23:27:32", + "duration": 7200000, + "percent": 1.45, + "rate": 1.88, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T23:27:32", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-31T07:28:30Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T23:27:32", + "duration": 1948000, + "expectedDuration": 7200000, + "percent": 1.45, + "rate": 1.88, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T23:27:32", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2017-12-31T07:28:30Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T00:00:00", + "duration": 7200000, + "percent": 1.45, + "rate": 2.1, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T00:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-31T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T00:00:00", + "duration": 5252000, + "expectedDuration": 7200000, + "percent": 1.45, + "rate": 2.1, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T00:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2017-12-31T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T01:27:32", + "duration": 7348000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T05:30:00", + "duration": 10163000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T08:19:23", + "duration": 227000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T08:23:10", + "duration": 410000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T08:30:00", + "duration": 1916000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T09:01:56", + "duration": 291000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T09:06:47", + "duration": 10393000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T00:00:00", + "duration": 2058000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T00:34:18", + "duration": 18000000, + "percent": 1.3, + "rate": 1.88, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T00:34:18", + "duration": 18000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-01-05T08:35:16Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T00:34:18", + "duration": 10542000, + "expectedDuration": 18000000, + "percent": 1.3, + "rate": 1.88, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T00:34:18", + "duration": 18000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-01-05T08:35:16Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T03:30:00", + "duration": 18000000, + "percent": 1.3, + "rate": 1.69, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T03:30:00", + "duration": 18000000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-01-05T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T03:30:00", + "duration": 7200000, + "expectedDuration": 18000000, + "percent": 1.3, + "rate": 1.69, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T03:30:00", + "duration": 18000000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-01-05T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T05:30:00", + "duration": 18000000, + "percent": 1.3, + "rate": 2.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T05:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-01-05T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T05:30:00", + "duration": 258000, + "expectedDuration": 18000000, + "percent": 1.3, + "rate": 2.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T05:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-01-05T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T05:34:18", + "duration": 10542000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T00:00:00", + "duration": 5352000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T01:29:12", + "duration": 16200000, + "percent": 1.45, + "rate": 2.1, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T01:29:12", + "duration": 16200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-01-06T09:30:10Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T01:29:12", + "duration": 7248000, + "expectedDuration": 16200000, + "percent": 1.45, + "rate": 2.1, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T01:29:12", + "duration": 16200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-01-06T09:30:10Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T03:30:00", + "duration": 16200000, + "percent": 1.45, + "rate": 1.88, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T03:30:00", + "duration": 16200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-01-06T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T03:30:00", + "duration": 7200000, + "expectedDuration": 16200000, + "percent": 1.45, + "rate": 1.88, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T03:30:00", + "duration": 16200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-01-06T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T05:30:00", + "duration": 16200000, + "percent": 1.45, + "rate": 2.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T05:30:00", + "duration": 16200000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-01-06T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T05:30:00", + "duration": 1752000, + "expectedDuration": 16200000, + "percent": 1.45, + "rate": 2.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T05:30:00", + "duration": 16200000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-01-06T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T05:59:12", + "duration": 9048000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T08:30:00", + "duration": 10301000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T11:21:41", + "duration": 1674000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T11:49:35", + "duration": 625000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T12:00:00", + "duration": 10354000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T14:52:34", + "duration": 729000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T15:04:43", + "duration": 10517000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T05:30:00", + "duration": 6107000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T07:11:47", + "duration": 3600000, + "percent": 0.35, + "rate": 0.54, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T07:11:47", + "duration": 3600000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-01-10T15:12:45Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T08:11:47", + "duration": 1093000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T08:30:00", + "duration": 5259000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T09:57:39", + "duration": 54000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T09:58:33", + "duration": 7287000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T22:00:00", + "duration": 4793000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T23:19:53", + "duration": 5171000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T00:46:04", + "duration": 9836000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T12:00:00", + "duration": 19060000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T17:17:40", + "duration": 298000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T17:22:38", + "duration": 2242000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T18:00:00", + "duration": 762000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T18:12:42", + "duration": 364000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T18:18:46", + "duration": 13274000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T08:30:00", + "duration": 3806000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T09:33:26", + "duration": 32400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T09:33:26", + "duration": 32400000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-01-19T17:34:24Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T09:33:26", + "duration": 8794000, + "expectedDuration": 32400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T09:33:26", + "duration": 32400000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-01-19T17:34:24Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T12:00:00", + "duration": 32400000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T12:00:00", + "duration": 32400000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-01-19T20:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T12:00:00", + "duration": 21600000, + "expectedDuration": 32400000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T12:00:00", + "duration": 32400000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-01-19T20:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T18:00:00", + "duration": 32400000, + "percent": 0.75, + "rate": 0.86, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T18:00:00", + "duration": 32400000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-01-20T02:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T18:00:00", + "duration": 2006000, + "expectedDuration": 32400000, + "percent": 0.75, + "rate": 0.86, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T18:00:00", + "duration": 32400000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-01-20T02:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T18:33:26", + "duration": 12394000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T08:30:00", + "duration": 12207000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T11:53:27", + "duration": 10800000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T11:53:27", + "duration": 10800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-01-20T19:54:25Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T11:53:27", + "duration": 393000, + "expectedDuration": 10800000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T11:53:27", + "duration": 10800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-01-20T19:54:25Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T12:00:00", + "duration": 10800000, + "percent": 0.65, + "rate": 0.42, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T12:00:00", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-01-20T20:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T12:00:00", + "duration": 10407000, + "expectedDuration": 10800000, + "percent": 0.65, + "rate": 0.42, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T12:00:00", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-01-20T20:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T14:53:27", + "duration": 11193000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T00:00:00", + "duration": 4261000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T01:11:01", + "duration": 404000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T01:17:45", + "duration": 7935000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T08:30:00", + "duration": 1757000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T08:59:17", + "duration": 695000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T09:10:52", + "duration": 10148000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T12:00:00", + "duration": 18043000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T17:00:43", + "duration": 2404000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T17:40:47", + "duration": 1153000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T00:00:00", + "duration": 4572000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T01:16:12", + "duration": 303000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T01:21:15", + "duration": 7725000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T08:30:00", + "duration": 1219000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T08:50:19", + "duration": 5400000, + "percent": 1.3, + "rate": 1.88, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T08:50:19", + "duration": 5400000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-01-31T16:51:17Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T10:20:19", + "duration": 5981000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T12:00:00", + "duration": 14758000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T16:05:58", + "duration": 375000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T16:12:13", + "duration": 6467000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T18:00:00", + "duration": 11599000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T21:13:19", + "duration": 711000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T21:25:10", + "duration": 2090000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T18:00:00", + "duration": 10305000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T20:51:45", + "duration": 7200000, + "percent": 0.19999999999999996, + "rate": 0.23, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T20:51:45", + "duration": 7200000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-02-04T04:52:43Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T20:51:45", + "duration": 4095000, + "expectedDuration": 7200000, + "percent": 0.19999999999999996, + "rate": 0.23, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T20:51:45", + "duration": 7200000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-02-04T04:52:43Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T22:00:00", + "duration": 7200000, + "percent": 0.19999999999999996, + "rate": 0.28, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-02-04T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T22:00:00", + "duration": 3105000, + "expectedDuration": 7200000, + "percent": 0.19999999999999996, + "rate": 0.28, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-02-04T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T22:51:45", + "duration": 4095000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T12:00:00", + "duration": 19370000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T17:22:50", + "duration": 3600000, + "percent": 0.7, + "rate": 0.45, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T17:22:50", + "duration": 3600000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-02-06T01:23:48Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T17:22:50", + "duration": 2230000, + "expectedDuration": 3600000, + "percent": 0.7, + "rate": 0.45, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T17:22:50", + "duration": 3600000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-02-06T01:23:48Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T18:00:00", + "duration": 3600000, + "percent": 0.7, + "rate": 0.8, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T18:00:00", + "duration": 3600000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-02-06T02:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T18:00:00", + "duration": 1370000, + "expectedDuration": 3600000, + "percent": 0.7, + "rate": 0.8, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T18:00:00", + "duration": 3600000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-02-06T02:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T18:22:50", + "duration": 13030000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T03:30:00", + "duration": 7580000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T05:36:20", + "duration": 249000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T05:40:29", + "duration": 10171000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T08:30:00", + "duration": 169000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T08:32:49", + "duration": 544000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T08:41:53", + "duration": 11887000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T12:00:00", + "duration": 16275000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T16:31:15", + "duration": 455000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T16:38:50", + "duration": 4870000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T18:00:00", + "duration": 13413000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T21:43:33", + "duration": 246000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T21:47:39", + "duration": 741000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:00:00", + "duration": 643000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:10:43", + "duration": 60000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:10:43", + "duration": 60000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-15T08:11:41Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:10:43", + "duration": 7000, + "expectedDuration": 60000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:10:43", + "duration": 60000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-15T08:11:41Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:10:50", + "duration": 273000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:15:23", + "duration": 28000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:15:51", + "duration": 7200000, + "percent": 1.3, + "rate": 1.95, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:15:51", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-15T08:16:49Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T02:15:51", + "duration": 4449000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T00:00:00", + "duration": 10840000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:00:40", + "duration": 10800000, + "percent": 1.45, + "rate": 2.17, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:00:40", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-16T11:01:38Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:00:40", + "duration": 1760000, + "expectedDuration": 10800000, + "percent": 1.45, + "rate": 2.17, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:00:40", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-16T11:01:38Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:30:00", + "duration": 10800000, + "percent": 1.45, + "rate": 1.95, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:30:00", + "duration": 10800000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-02-16T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:30:00", + "duration": 7200000, + "expectedDuration": 10800000, + "percent": 1.45, + "rate": 1.95, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:30:00", + "duration": 10800000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-02-16T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T05:30:00", + "duration": 10800000, + "percent": 1.45, + "rate": 2.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T05:30:00", + "duration": 10800000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-02-16T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T05:30:00", + "duration": 1840000, + "expectedDuration": 10800000, + "percent": 1.45, + "rate": 2.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T05:30:00", + "duration": 10800000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-02-16T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T06:00:40", + "duration": 8960000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T05:30:00", + "duration": 9662000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T08:11:02", + "duration": 6831000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T10:04:53", + "duration": 973000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T10:21:06", + "duration": 97000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T10:22:43", + "duration": 5837000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T12:00:00", + "duration": 4664000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T13:17:44", + "duration": 7380000, + "percent": 1.5, + "rate": 0.97, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T13:17:44", + "duration": 7380000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-02-18T21:18:42Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T13:17:44", + "duration": 7325000, + "expectedDuration": 7380000, + "percent": 1.5, + "rate": 0.97, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T13:17:44", + "duration": 7380000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-02-18T21:18:42Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T15:19:49", + "duration": 9611000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T22:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T22:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T22:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T05:30:00", + "duration": 7957000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T07:42:37", + "duration": 35000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T07:43:12", + "duration": 2808000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T08:30:00", + "duration": 8781000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T10:56:21", + "duration": 254000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T11:00:35", + "duration": 3565000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T00:00:00", + "duration": 4542000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T01:15:42", + "duration": 10800000, + "percent": 0.7, + "rate": 1.05, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T01:15:42", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-22T09:16:40Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T01:15:42", + "duration": 8058000, + "expectedDuration": 10800000, + "percent": 0.7, + "rate": 1.05, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T01:15:42", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-22T09:16:40Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T03:30:00", + "duration": 10800000, + "percent": 0.7, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T03:30:00", + "duration": 10800000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-02-22T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T03:30:00", + "duration": 2742000, + "expectedDuration": 10800000, + "percent": 0.7, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T03:30:00", + "duration": 10800000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-02-22T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T04:15:42", + "duration": 4458000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T18:00:00", + "duration": 366000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T18:06:06", + "duration": 21600000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T18:06:06", + "duration": 21600000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-02-23T02:07:04Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T18:06:06", + "duration": 14034000, + "expectedDuration": 21600000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T18:06:06", + "duration": 21600000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-02-23T02:07:04Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T22:00:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T22:00:00", + "duration": 21600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-02-23T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T22:00:00", + "duration": 7200000, + "expectedDuration": 21600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T22:00:00", + "duration": 21600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-02-23T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T00:00:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T00:00:00", + "duration": 21600000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-23T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T00:00:00", + "duration": 366000, + "expectedDuration": 21600000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T00:00:00", + "duration": 21600000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-23T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T00:06:06", + "duration": 9204000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T02:39:30", + "duration": 18000000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T02:39:30", + "duration": 18000000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-23T10:40:28Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T02:39:30", + "duration": 3030000, + "expectedDuration": 18000000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T02:39:30", + "duration": 18000000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-23T10:40:28Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T03:30:00", + "duration": 18000000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T03:30:00", + "duration": 18000000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-02-23T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T03:30:00", + "duration": 7200000, + "expectedDuration": 18000000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T03:30:00", + "duration": 18000000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-02-23T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T05:30:00", + "duration": 18000000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T05:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-02-23T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T05:30:00", + "duration": 7770000, + "expectedDuration": 18000000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T05:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-02-23T13:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T07:39:30", + "duration": 3030000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T08:30:00", + "duration": 8164000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T10:46:04", + "duration": 18000000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T10:46:04", + "duration": 18000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-02-23T18:47:02Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T10:46:04", + "duration": 4436000, + "expectedDuration": 18000000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T10:46:04", + "duration": 18000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-02-23T18:47:02Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T12:00:00", + "duration": 18000000, + "percent": 0.65, + "rate": 0.42, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T12:00:00", + "duration": 18000000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-02-23T20:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T12:00:00", + "duration": 13564000, + "expectedDuration": 18000000, + "percent": 0.65, + "rate": 0.42, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T12:00:00", + "duration": 18000000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-02-23T20:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T15:46:04", + "duration": 8036000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T12:00:00", + "duration": 21410000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T17:56:50", + "duration": 2163000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T18:32:53", + "duration": 12427000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T22:00:00", + "duration": 5415000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T23:30:15", + "duration": 7200000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T23:30:15", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-02-26T07:31:13Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T23:30:15", + "duration": 1785000, + "expectedDuration": 7200000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T23:30:15", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-02-26T07:31:13Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T00:00:00", + "duration": 7200000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T00:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-26T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T00:00:00", + "duration": 5415000, + "expectedDuration": 7200000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T00:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-02-26T08:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T01:30:15", + "duration": 7185000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T08:30:00", + "duration": 345000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T08:35:45", + "duration": 5400000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T08:35:45", + "duration": 5400000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-02-27T16:36:43Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T10:05:45", + "duration": 6855000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T18:00:00", + "duration": 9705000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T20:41:45", + "duration": 7200000, + "percent": 1.3, + "rate": 1.49, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T20:41:45", + "duration": 7200000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-02-28T04:42:43Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T20:41:45", + "duration": 4695000, + "expectedDuration": 7200000, + "percent": 1.3, + "rate": 1.49, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T20:41:45", + "duration": 7200000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-02-28T04:42:43Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T22:00:00", + "duration": 7200000, + "percent": 1.3, + "rate": 1.88, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-02-28T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T22:00:00", + "duration": 2505000, + "expectedDuration": 7200000, + "percent": 1.3, + "rate": 1.88, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-02-28T06:00:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T22:41:45", + "duration": 4695000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T00:00:00", + "duration": 5211000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T01:26:51", + "duration": 199000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T01:30:10", + "duration": 147000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T01:32:37", + "duration": 12600000, + "percent": 0.75, + "rate": 1.12, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T01:32:37", + "duration": 12600000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-02-28T09:33:35Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T01:32:37", + "duration": 7043000, + "expectedDuration": 12600000, + "percent": 0.75, + "rate": 1.12, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T01:32:37", + "duration": 12600000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-02-28T09:33:35Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T03:30:00", + "duration": 12600000, + "percent": 0.75, + "rate": 1.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T03:30:00", + "duration": 12600000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-02-28T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T03:30:00", + "duration": 5557000, + "expectedDuration": 12600000, + "percent": 0.75, + "rate": 1.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T03:30:00", + "duration": 12600000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-02-28T11:30:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T05:02:37", + "duration": 1643000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T12:00:00", + "duration": 91000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T12:01:31", + "duration": 7200000, + "percent": 1.35, + "rate": 0.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T12:01:31", + "duration": 7200000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-03-02T20:02:29Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T14:01:31", + "duration": 14309000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T00:00:00", + "duration": 8771000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T02:26:11", + "duration": 272000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T02:30:43", + "duration": 3557000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T08:30:00", + "duration": 5906000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T10:08:26", + "duration": 2274000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T10:46:20", + "duration": 4420000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T18:00:00", + "duration": 2434000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T18:40:34", + "duration": 3332000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T19:36:06", + "duration": 8634000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T22:00:00", + "duration": 7042000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T23:57:22", + "duration": 114000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T23:59:16", + "duration": 44000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T08:30:00", + "duration": 135000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T08:32:15", + "duration": 360000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T09:38:15", + "duration": 8505000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T00:00:00", + "duration": 5721000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T01:35:21", + "duration": 660000, + "percent": 0.6, + "rate": 0.9, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T01:35:21", + "duration": 660000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-03-14T08:36:19Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T01:35:21", + "duration": 638000, + "expectedDuration": 660000, + "percent": 0.6, + "rate": 0.9, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T01:35:21", + "duration": 660000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-03-14T08:36:19Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T01:45:59", + "duration": 6241000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T18:00:00", + "duration": 12763000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T21:32:43", + "duration": 200000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T21:36:03", + "duration": 1437000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T00:00:00", + "duration": 7717000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T02:08:37", + "duration": 9000000, + "percent": 1.2, + "rate": 1.8, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T02:08:37", + "duration": 9000000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-03-16T09:09:35Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T02:08:37", + "duration": 4883000, + "expectedDuration": 9000000, + "percent": 1.2, + "rate": 1.8, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T02:08:37", + "duration": 9000000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-03-16T09:09:35Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T03:30:00", + "duration": 9000000, + "percent": 1.2, + "rate": 1.62, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T03:30:00", + "duration": 9000000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-03-16T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T03:30:00", + "duration": 4117000, + "expectedDuration": 9000000, + "percent": 1.2, + "rate": 1.62, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T03:30:00", + "duration": 9000000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-03-16T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T04:38:37", + "duration": 3083000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T00:00:00", + "duration": 1387000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T00:23:07", + "duration": 5575000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T01:56:02", + "duration": 5638000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T00:00:00", + "duration": 5074000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T01:24:34", + "duration": 3600000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T01:24:34", + "duration": 3600000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-03-20T08:25:32Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T02:24:34", + "duration": 3926000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T12:00:00", + "duration": 14636000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T16:03:56", + "duration": 156000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T16:06:32", + "duration": 6808000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T12:00:00", + "duration": 261000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T12:04:21", + "duration": 241000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T12:08:22", + "duration": 21098000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T08:30:00", + "duration": 5750000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T10:05:50", + "duration": 188000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T10:08:58", + "duration": 6662000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T12:00:00", + "duration": 17191000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T16:46:31", + "duration": 4727000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T18:05:18", + "duration": 14082000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T18:00:00", + "duration": 2581000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T18:43:01", + "duration": 67000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T21:44:08", + "duration": 952000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T18:00:00", + "duration": 9738000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T20:42:18", + "duration": 1004000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T20:59:02", + "duration": 3658000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T00:00:00", + "duration": 12403000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:26:43", + "duration": 7200000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:26:43", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-03-30T07:27:41Z", + "timezoneOffset": -180, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:26:43", + "duration": 197000, + "expectedDuration": 7200000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:26:43", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-03-30T07:27:41Z", + "timezoneOffset": -180, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:30:00", + "duration": 7200000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-03-30T07:30:58Z", + "timezoneOffset": -180, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:30:00", + "duration": 7003000, + "expectedDuration": 7200000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-03-30T07:30:58Z", + "timezoneOffset": -180, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T05:26:43", + "duration": 197000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T18:00:00", + "duration": 3804000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T19:03:24", + "duration": 476000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T19:11:20", + "duration": 10120000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T08:30:00", + "duration": 3078000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T09:21:18", + "duration": 5400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T09:21:18", + "duration": 5400000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-04-03T13:22:16Z", + "timezoneOffset": -180, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T10:51:18", + "duration": 4122000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T18:00:00", + "duration": 8562000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T20:22:42", + "duration": 87000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T17:24:09", + "duration": 2151000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T18:00:00", + "duration": 10423000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T20:53:43", + "duration": 2326000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T21:32:29", + "duration": 1651000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T08:30:00", + "duration": 11164000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T11:36:04", + "duration": 7381000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T13:39:05", + "duration": 15655000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T18:00:00", + "duration": 6679000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T19:51:19", + "duration": 1653000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T20:18:52", + "duration": 6068000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T08:30:00", + "duration": 6131000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T10:12:11", + "duration": 1800000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T10:12:11", + "duration": 1800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-04-10T17:13:09Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T10:42:11", + "duration": 4669000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T12:00:00", + "duration": 243000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T12:04:03", + "duration": 36000000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T12:04:03", + "duration": 36000000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-04-11T19:05:01Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T12:04:03", + "duration": 21357000, + "expectedDuration": 36000000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T12:04:03", + "duration": 36000000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-04-11T19:05:01Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T18:00:00", + "duration": 36000000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T18:00:00", + "duration": 36000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-04-12T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T18:00:00", + "duration": 14400000, + "expectedDuration": 36000000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T18:00:00", + "duration": 36000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-04-12T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T22:00:00", + "duration": 36000000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T22:00:00", + "duration": 36000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-04-12T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T22:00:00", + "duration": 242000, + "expectedDuration": 36000000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T22:00:00", + "duration": 36000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-04-12T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T22:04:02", + "duration": 6958000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T08:30:00", + "duration": 321000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T08:35:21", + "duration": 28800000, + "percent": 0.7, + "rate": 1.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T08:35:21", + "duration": 28800000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-04-12T15:36:19Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T08:35:21", + "duration": 12279000, + "expectedDuration": 28800000, + "percent": 0.7, + "rate": 1.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T08:35:21", + "duration": 28800000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-04-12T15:36:19Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T12:00:00", + "duration": 28200000, + "percent": 0.7, + "rate": 0.45, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T12:00:00", + "duration": 28200000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-04-12T19:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T12:00:00", + "duration": 15906000, + "expectedDuration": 28200000, + "percent": 0.7, + "rate": 0.45, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T12:00:00", + "duration": 28200000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-04-12T19:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T16:25:06", + "duration": 17000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T16:25:23", + "duration": 12600000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T16:25:23", + "duration": 12600000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-04-12T23:26:21Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T16:25:23", + "duration": 5677000, + "expectedDuration": 12600000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T16:25:23", + "duration": 12600000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-04-12T23:26:21Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T18:00:00", + "duration": 12600000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T18:00:00", + "duration": 12600000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-04-13T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T18:00:00", + "duration": 6923000, + "expectedDuration": 12600000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T18:00:00", + "duration": 12600000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-04-13T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T19:55:23", + "duration": 7477000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T22:00:00", + "duration": 5512000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T23:31:52", + "duration": 351000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T23:37:43", + "duration": 562000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T23:47:05", + "duration": 36000000, + "percent": 0.6, + "rate": 0.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T23:47:05", + "duration": 36000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-04-13T06:48:03Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T23:47:05", + "duration": 775000, + "expectedDuration": 36000000, + "percent": 0.6, + "rate": 0.87, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T23:47:05", + "duration": 36000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-04-13T06:48:03Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:00:00", + "duration": 840000, + "percent": 0.6, + "rate": 0.9, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:00:00", + "duration": 840000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-04-13T07:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:00:00", + "duration": 62000, + "expectedDuration": 840000, + "percent": 0.6, + "rate": 0.9, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:00:00", + "duration": 840000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-04-13T07:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:01:02", + "duration": 13000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:01:15", + "duration": 10380000, + "percent": 0.5, + "rate": 0.75, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:01:15", + "duration": 10380000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-04-13T07:02:13Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:01:15", + "duration": 10367000, + "expectedDuration": 10380000, + "percent": 0.5, + "rate": 0.75, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:01:15", + "duration": 10380000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-04-13T07:02:13Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T02:54:02", + "duration": 17000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T02:54:19", + "duration": 27000000, + "percent": 0.35, + "rate": 0.52, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T02:54:19", + "duration": 27000000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-04-13T09:55:17Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T02:54:19", + "duration": 2141000, + "expectedDuration": 27000000, + "percent": 0.35, + "rate": 0.52, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T02:54:19", + "duration": 27000000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-04-13T09:55:17Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T03:30:00", + "duration": 27000000, + "percent": 0.35, + "rate": 0.47, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T03:30:00", + "duration": 27000000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-04-13T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T03:30:00", + "duration": 7200000, + "expectedDuration": 27000000, + "percent": 0.35, + "rate": 0.47, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T03:30:00", + "duration": 27000000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-04-13T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T05:30:00", + "duration": 14700000, + "percent": 0.35, + "rate": 0.54, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T05:30:00", + "duration": 14700000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-04-13T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T05:30:00", + "duration": 5354000, + "expectedDuration": 14700000, + "percent": 0.35, + "rate": 0.54, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T05:30:00", + "duration": 14700000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-04-13T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T06:59:14", + "duration": 5446000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T08:30:00", + "duration": 1684000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T08:58:04", + "duration": 3600000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T08:58:04", + "duration": 3600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-04-13T15:59:02Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T09:58:04", + "duration": 211000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T10:01:35", + "duration": 3600000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T10:01:35", + "duration": 3600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-04-13T17:02:33Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T11:01:35", + "duration": 3505000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T12:00:00", + "duration": 1514000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T12:25:14", + "duration": 12840000, + "percent": 0.55, + "rate": 0.35, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T12:25:14", + "duration": 12840000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-04-13T19:26:12Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T12:25:14", + "duration": 12810000, + "expectedDuration": 12840000, + "percent": 0.55, + "rate": 0.35, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T12:25:14", + "duration": 12840000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-04-13T19:26:12Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T15:58:44", + "duration": 8000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T15:58:52", + "duration": 5400000, + "percent": 1.25, + "rate": 0.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T15:58:52", + "duration": 5400000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-04-13T22:59:50Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T17:28:52", + "duration": 1868000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T18:00:00", + "duration": 4291000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T19:11:31", + "duration": 60000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T19:11:31", + "duration": 60000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-04-14T02:12:29Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T19:11:31", + "duration": 48000, + "expectedDuration": 60000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T19:11:31", + "duration": 60000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-04-14T02:12:29Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T19:12:19", + "duration": 10061000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T00:00:00", + "duration": 2499000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T00:41:39", + "duration": 7200000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T00:41:39", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-04-14T07:42:37Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T02:41:39", + "duration": 2901000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T05:30:00", + "duration": 10759000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T08:29:19", + "duration": 4125000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T09:38:04", + "duration": 8516000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T12:00:00", + "duration": 4493000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T13:14:53", + "duration": 3600000, + "percent": 0.9, + "rate": 0.58, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T13:14:53", + "duration": 3600000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-04-14T20:15:51Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T14:14:53", + "duration": 13507000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T05:30:00", + "duration": 8560000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T07:52:40", + "duration": 8961000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T10:22:01", + "duration": 5879000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T22:00:00", + "duration": 6208000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T23:43:28", + "duration": 7200000, + "percent": 1.1, + "rate": 1.59, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T23:43:28", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-04-18T06:44:26Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T23:43:28", + "duration": 992000, + "expectedDuration": 7200000, + "percent": 1.1, + "rate": 1.59, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T23:43:28", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-04-18T06:44:26Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T00:00:00", + "duration": 7200000, + "percent": 1.1, + "rate": 1.65, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T00:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-04-18T07:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T00:00:00", + "duration": 6208000, + "expectedDuration": 7200000, + "percent": 1.1, + "rate": 1.65, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T00:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-04-18T07:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T01:43:28", + "duration": 6392000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T12:00:00", + "duration": 11187000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T15:06:27", + "duration": 3600000, + "percent": 0.7, + "rate": 0.45, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T15:06:27", + "duration": 3600000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-04-18T22:07:25Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T16:06:27", + "duration": 6813000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T08:30:00", + "duration": 7374000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T10:32:54", + "duration": 790000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T10:46:04", + "duration": 4436000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T05:30:00", + "duration": 10425000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T08:23:45", + "duration": 375000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T12:00:00", + "duration": 10788000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T14:59:48", + "duration": 3678000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T16:01:06", + "duration": 7134000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T12:00:00", + "duration": 9679000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T14:41:19", + "duration": 10800000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T14:41:19", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-04-22T21:42:17Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T17:41:19", + "duration": 1121000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T22:00:00", + "duration": 4227000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T23:10:27", + "duration": 586000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T23:20:13", + "duration": 2387000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T18:00:00", + "duration": 13412000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T21:43:32", + "duration": 200000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T21:46:52", + "duration": 788000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T00:00:00", + "duration": 3746000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:02:26", + "duration": 180000, + "percent": 0.7, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:02:26", + "duration": 180000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-04-26T08:03:24Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:02:26", + "duration": 128000, + "expectedDuration": 180000, + "percent": 0.7, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:02:26", + "duration": 180000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-04-26T08:03:24Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:04:34", + "duration": 11000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:04:45", + "duration": 18000000, + "percent": 0.85, + "rate": 1.31, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:04:45", + "duration": 18000000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-04-26T08:05:43Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:04:45", + "duration": 8715000, + "expectedDuration": 18000000, + "percent": 0.85, + "rate": 1.31, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:04:45", + "duration": 18000000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-04-26T08:05:43Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T03:30:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.19, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T03:30:00", + "duration": 18000000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-04-26T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T03:30:00", + "duration": 7200000, + "expectedDuration": 18000000, + "percent": 0.85, + "rate": 1.19, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T03:30:00", + "duration": 18000000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-04-26T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T05:30:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.36, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T05:30:00", + "duration": 18000000, + "rate": 1.6, + "scheduleName": "basal 3", + "time": "2018-04-26T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T05:30:00", + "duration": 2085000, + "expectedDuration": 18000000, + "percent": 0.85, + "rate": 1.36, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T05:30:00", + "duration": 18000000, + "rate": 1.6, + "scheduleName": "basal 3", + "time": "2018-04-26T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T06:04:45", + "duration": 8715000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T00:00:00", + "duration": 10498000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T02:54:58", + "duration": 21600000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T02:54:58", + "duration": 21600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-04-27T09:55:56Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T02:54:58", + "duration": 2102000, + "expectedDuration": 21600000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T02:54:58", + "duration": 21600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-04-27T09:55:56Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T03:30:00", + "duration": 21600000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T03:30:00", + "duration": 21600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-04-27T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T03:30:00", + "duration": 7200000, + "expectedDuration": 21600000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T03:30:00", + "duration": 21600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-04-27T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T05:30:00", + "duration": 21600000, + "percent": 0.75, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T05:30:00", + "duration": 21600000, + "rate": 1.6, + "scheduleName": "basal 3", + "time": "2018-04-27T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T05:30:00", + "duration": 10800000, + "expectedDuration": 21600000, + "percent": 0.75, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T05:30:00", + "duration": 21600000, + "rate": 1.6, + "scheduleName": "basal 3", + "time": "2018-04-27T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T08:30:00", + "duration": 21600000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T08:30:00", + "duration": 21600000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-04-27T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T08:30:00", + "duration": 1498000, + "expectedDuration": 21600000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T08:30:00", + "duration": 21600000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-04-27T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T08:54:58", + "duration": 11102000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T22:00:00", + "duration": 4513000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T23:15:13", + "duration": 147000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T23:17:40", + "duration": 2540000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T00:00:00", + "duration": 635000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T00:10:35", + "duration": 315000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T00:15:50", + "duration": 11650000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T18:00:00", + "duration": 1631000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T18:27:11", + "duration": 3420000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T18:27:11", + "duration": 3420000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-03T01:28:09Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T18:27:11", + "duration": 3419000, + "expectedDuration": 3420000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T18:27:11", + "duration": 3420000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-03T01:28:09Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T19:24:10", + "duration": 9350000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T05:30:00", + "duration": 3903000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T06:35:03", + "duration": 7200000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T06:35:03", + "duration": 7200000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-05-03T13:36:01Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T06:35:03", + "duration": 6897000, + "expectedDuration": 7200000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T06:35:03", + "duration": 7200000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-05-03T13:36:01Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T08:30:00", + "duration": 7200000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T08:30:00", + "duration": 7200000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-03T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T08:30:00", + "duration": 303000, + "expectedDuration": 7200000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T08:30:00", + "duration": 7200000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-03T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T08:35:03", + "duration": 2092000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T09:09:55", + "duration": 43200000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T09:09:55", + "duration": 43200000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-03T16:10:53Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T09:09:55", + "duration": 10205000, + "expectedDuration": 43200000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T09:09:55", + "duration": 43200000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-03T16:10:53Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T12:00:00", + "duration": 16200000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T12:00:00", + "duration": 16200000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-05-03T19:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T12:00:00", + "duration": 5994000, + "expectedDuration": 16200000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T12:00:00", + "duration": 16200000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-05-03T19:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T13:39:54", + "duration": 221000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T13:43:35", + "duration": 10550000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T16:39:25", + "duration": 21498000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T22:37:43", + "duration": 4937000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T00:00:00", + "duration": 5097000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T01:24:57", + "duration": 30600000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T01:24:57", + "duration": 30600000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-05-04T08:25:55Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T01:24:57", + "duration": 7503000, + "expectedDuration": 30600000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T01:24:57", + "duration": 30600000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-05-04T08:25:55Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T03:30:00", + "duration": 30600000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T03:30:00", + "duration": 30600000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-05-04T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T03:30:00", + "duration": 7200000, + "expectedDuration": 30600000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T03:30:00", + "duration": 30600000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-05-04T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T05:30:00", + "duration": 30600000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T05:30:00", + "duration": 30600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-05-04T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T05:30:00", + "duration": 10800000, + "expectedDuration": 30600000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T05:30:00", + "duration": 30600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-05-04T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T08:30:00", + "duration": 30600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T08:30:00", + "duration": 30600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-05-04T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T08:30:00", + "duration": 5097000, + "expectedDuration": 30600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T08:30:00", + "duration": 30600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-05-04T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T09:54:57", + "duration": 4178000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T11:04:35", + "duration": 41400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T11:04:35", + "duration": 41400000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-04T18:05:33Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T11:04:35", + "duration": 3325000, + "expectedDuration": 41400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T11:04:35", + "duration": 41400000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-04T18:05:33Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T12:00:00", + "duration": 41400000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T12:00:00", + "duration": 41400000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-05-04T19:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T12:00:00", + "duration": 21600000, + "expectedDuration": 41400000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T12:00:00", + "duration": 41400000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-05-04T19:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T18:00:00", + "duration": 41400000, + "percent": 0.75, + "rate": 0.86, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T18:00:00", + "duration": 41400000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-05T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T18:00:00", + "duration": 14400000, + "expectedDuration": 41400000, + "percent": 0.75, + "rate": 0.86, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T18:00:00", + "duration": 41400000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-05T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T22:00:00", + "duration": 41400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T22:00:00", + "duration": 41400000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-05T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T22:00:00", + "duration": 2075000, + "expectedDuration": 41400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T22:00:00", + "duration": 41400000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-05T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T22:34:35", + "duration": 5125000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T00:00:00", + "duration": 4232000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T01:10:32", + "duration": 28800000, + "percent": 0.75, + "rate": 1.12, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T01:10:32", + "duration": 28800000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-05-05T08:11:30Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T01:10:32", + "duration": 8368000, + "expectedDuration": 28800000, + "percent": 0.75, + "rate": 1.12, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T01:10:32", + "duration": 28800000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-05-05T08:11:30Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T03:30:00", + "duration": 28800000, + "percent": 0.75, + "rate": 1.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T03:30:00", + "duration": 28800000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-05-05T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T03:30:00", + "duration": 7200000, + "expectedDuration": 28800000, + "percent": 0.75, + "rate": 1.01, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T03:30:00", + "duration": 28800000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-05-05T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T05:30:00", + "duration": 28800000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T05:30:00", + "duration": 28800000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-05-05T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T05:30:00", + "duration": 10800000, + "expectedDuration": 28800000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T05:30:00", + "duration": 28800000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-05-05T12:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T08:30:00", + "duration": 28800000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T08:30:00", + "duration": 28800000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-05T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T08:30:00", + "duration": 2432000, + "expectedDuration": 28800000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T08:30:00", + "duration": 28800000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-05T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T09:10:32", + "duration": 10168000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T05:30:00", + "duration": 10250000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:20:50", + "duration": 28800000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:20:50", + "duration": 28800000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-05-06T15:21:48Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:20:50", + "duration": 550000, + "expectedDuration": 28800000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:20:50", + "duration": 28800000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-05-06T15:21:48Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:30:00", + "duration": 28800000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:30:00", + "duration": 28800000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-06T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:30:00", + "duration": 12600000, + "expectedDuration": 28800000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:30:00", + "duration": 28800000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-06T15:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T12:00:00", + "duration": 28800000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T12:00:00", + "duration": 28800000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-05-06T19:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T12:00:00", + "duration": 15650000, + "expectedDuration": 28800000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T12:00:00", + "duration": 28800000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-05-06T19:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T16:20:50", + "duration": 5950000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T18:00:00", + "duration": 9910000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T20:45:10", + "duration": 257000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T20:49:27", + "duration": 4233000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T03:30:00", + "duration": 4311000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T04:41:51", + "duration": 18428000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T09:48:59", + "duration": 7861000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T18:00:00", + "duration": 11857000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T21:17:37", + "duration": 10800000, + "percent": 1.15, + "rate": 1.32, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T21:17:37", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-11T04:18:35Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T21:17:37", + "duration": 2543000, + "expectedDuration": 10800000, + "percent": 1.15, + "rate": 1.32, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T21:17:37", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-11T04:18:35Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T22:00:00", + "duration": 5460000, + "percent": 1.15, + "rate": 1.66, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T22:00:00", + "duration": 5460000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-11T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T22:00:00", + "duration": 2891000, + "expectedDuration": 5460000, + "percent": 1.15, + "rate": 1.66, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T22:00:00", + "duration": 5460000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-05-11T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T22:48:11", + "duration": 2421000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T23:28:32", + "duration": 3600000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T23:28:32", + "duration": 3600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-05-11T06:29:30Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T23:28:32", + "duration": 1888000, + "expectedDuration": 3600000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T23:28:32", + "duration": 3600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-05-11T06:29:30Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T00:00:00", + "duration": 3600000, + "percent": 1.25, + "rate": 1.93, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T00:00:00", + "duration": 3600000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-05-11T07:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T00:00:00", + "duration": 1712000, + "expectedDuration": 3600000, + "percent": 1.25, + "rate": 1.93, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T00:00:00", + "duration": 3600000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-05-11T07:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T00:28:32", + "duration": 10888000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T12:00:00", + "duration": 21052000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T17:50:52", + "duration": 10800000, + "percent": 1.25, + "rate": 0.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T17:50:52", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-05-13T00:51:50Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T17:50:52", + "duration": 548000, + "expectedDuration": 10800000, + "percent": 1.25, + "rate": 0.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T17:50:52", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-05-13T00:51:50Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T18:00:00", + "duration": 10800000, + "percent": 1.25, + "rate": 1.43, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T18:00:00", + "duration": 10800000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-05-13T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T18:00:00", + "duration": 10252000, + "expectedDuration": 10800000, + "percent": 1.25, + "rate": 1.43, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T18:00:00", + "duration": 10800000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-05-13T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T20:50:52", + "duration": 4148000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T05:30:00", + "duration": 1821000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T06:00:21", + "duration": 217000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T06:03:58", + "duration": 8762000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T18:00:00", + "duration": 2689000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T18:44:49", + "duration": 3986000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T19:51:15", + "duration": 7725000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T18:00:00", + "duration": 8609000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T20:23:29", + "duration": 9000000, + "percent": 1.5, + "rate": 1.72, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T20:23:29", + "duration": 9000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-16T03:24:27Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T20:23:29", + "duration": 5791000, + "expectedDuration": 9000000, + "percent": 1.5, + "rate": 1.72, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T20:23:29", + "duration": 9000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-16T03:24:27Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T22:00:00", + "duration": 7140000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T22:00:00", + "duration": 7140000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-05-16T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T22:00:00", + "duration": 1292000, + "expectedDuration": 7140000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T22:00:00", + "duration": 7140000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-05-16T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T22:21:32", + "duration": 5908000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T12:00:00", + "duration": 16133000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T16:28:53", + "duration": 113000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T16:30:46", + "duration": 5354000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T12:00:00", + "duration": 19563000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T17:26:03", + "duration": 368000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T17:32:11", + "duration": 1669000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T22:00:00", + "duration": 1859000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T22:30:59", + "duration": 3600000, + "percent": 1.95, + "rate": 2.82, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T22:30:59", + "duration": 3600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-05-23T05:31:57Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T23:30:59", + "duration": 1741000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T08:30:00", + "duration": 8897000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T10:58:17", + "duration": 1755000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T11:27:32", + "duration": 1948000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T12:00:00", + "duration": 19655000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T17:27:35", + "duration": 375000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T17:33:50", + "duration": 1570000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T18:00:00", + "duration": 13374000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T21:42:54", + "duration": 10800000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T21:42:54", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-24T04:43:52Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T21:42:54", + "duration": 1026000, + "expectedDuration": 10800000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T21:42:54", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-05-24T04:43:52Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T22:00:00", + "duration": 10800000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T22:00:00", + "duration": 10800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-05-24T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T22:00:00", + "duration": 7200000, + "expectedDuration": 10800000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T22:00:00", + "duration": 10800000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-05-24T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T00:00:00", + "duration": 10800000, + "percent": 1.4, + "rate": 2.1, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T00:00:00", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-05-24T07:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T00:00:00", + "duration": 2574000, + "expectedDuration": 10800000, + "percent": 1.4, + "rate": 2.1, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T00:00:00", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-05-24T07:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T00:42:54", + "duration": 10026000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T08:30:00", + "duration": 11426000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T11:40:26", + "duration": 7949000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T13:52:55", + "duration": 14825000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T08:30:00", + "duration": 2522000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T09:12:02", + "duration": 14514000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T13:13:56", + "duration": 17164000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T18:00:00", + "duration": 14339000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T21:58:59", + "duration": 1800000, + "percent": 0.09999999999999998, + "rate": 0.11, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T21:58:59", + "duration": 1800000, + "rate": 1.1, + "scheduleName": "basal 3", + "time": "2018-05-30T04:59:57Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T21:58:59", + "duration": 61000, + "expectedDuration": 1800000, + "percent": 0.09999999999999998, + "rate": 0.11, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T21:58:59", + "duration": 1800000, + "rate": 1.1, + "scheduleName": "basal 3", + "time": "2018-05-30T04:59:57Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T22:00:00", + "duration": 1800000, + "percent": 0.09999999999999998, + "rate": 0.14, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T22:00:00", + "duration": 1800000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-05-30T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T22:00:00", + "duration": 1739000, + "expectedDuration": 1800000, + "percent": 0.09999999999999998, + "rate": 0.14, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T22:00:00", + "duration": 1800000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-05-30T05:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T22:28:59", + "duration": 5461000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T12:00:00", + "duration": 20380000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T17:39:40", + "duration": 3600000, + "percent": 0.65, + "rate": 0.42, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T17:39:40", + "duration": 3600000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-05-31T00:40:38Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T17:39:40", + "duration": 1220000, + "expectedDuration": 3600000, + "percent": 0.65, + "rate": 0.42, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T17:39:40", + "duration": 3600000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-05-31T00:40:38Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T18:00:00", + "duration": 3600000, + "percent": 0.65, + "rate": 0.74, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T18:00:00", + "duration": 3600000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-05-31T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T18:00:00", + "duration": 2380000, + "expectedDuration": 3600000, + "percent": 0.65, + "rate": 0.74, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T18:00:00", + "duration": 3600000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-05-31T01:00:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T18:39:40", + "duration": 12020000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T22:00:00", + "duration": 1941000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T22:32:21", + "duration": 332000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T22:37:53", + "duration": 4927000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T00:00:00", + "duration": 7844000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T02:10:44", + "duration": 5400000, + "percent": 0.6, + "rate": 0.9, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T02:10:44", + "duration": 5400000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-06-01T09:11:42Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T02:10:44", + "duration": 4756000, + "expectedDuration": 5400000, + "percent": 0.6, + "rate": 0.9, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T02:10:44", + "duration": 5400000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-06-01T09:11:42Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T03:30:00", + "duration": 5400000, + "percent": 0.6, + "rate": 0.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T03:30:00", + "duration": 5400000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-06-01T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T03:30:00", + "duration": 644000, + "expectedDuration": 5400000, + "percent": 0.6, + "rate": 0.81, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T03:30:00", + "duration": 5400000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-06-01T10:30:58Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T03:40:44", + "duration": 6556000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T22:00:00", + "duration": 89000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T22:01:29", + "duration": 427000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T22:08:36", + "duration": 6684000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T12:00:00", + "duration": 6521000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:48:41", + "duration": 180000, + "percent": 0.6, + "rate": 0.39, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:48:41", + "duration": 180000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-06-03T20:49:39Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:48:41", + "duration": 154000, + "expectedDuration": 180000, + "percent": 0.6, + "rate": 0.39, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:48:41", + "duration": 180000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-06-03T20:49:39Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:51:15", + "duration": 329000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:56:44", + "duration": 5400000, + "percent": 1.2, + "rate": 0.78, + "suppressed": { + "conversionOffset": -3658000, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:56:44", + "duration": 5400000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-06-03T20:57:42Z", + "timezoneOffset": -360, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T15:26:44", + "duration": 9196000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T00:00:00", + "duration": 2718000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T00:45:18", + "duration": 410000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T00:52:08", + "duration": 9472000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T18:00:00", + "duration": 9098000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T20:31:38", + "duration": 238000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T20:35:36", + "duration": 5064000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T12:00:00", + "duration": 6090000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T13:41:30", + "duration": 277000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T13:46:07", + "duration": 8525000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-07T15:08:12", + "duration": 13000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T16:08:25", + "duration": 10295000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-07T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T12:00:00", + "duration": 537000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T12:08:57", + "duration": 190000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T12:12:07", + "duration": 20873000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T12:00:00", + "duration": 3798000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T13:03:18", + "duration": 482000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T14:12:18", + "duration": 13662000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T03:30:00", + "duration": 3971000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T04:36:11", + "duration": 250000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T04:40:21", + "duration": 2979000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T22:00:00", + "duration": 3091000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T22:51:31", + "duration": 1929000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T23:23:40", + "duration": 2180000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T12:00:00", + "duration": 2125000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T12:35:25", + "duration": 1737000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T13:04:22", + "duration": 17738000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T00:00:00", + "duration": 1723000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T00:28:43", + "duration": 27000000, + "percent": 0.65, + "rate": 0.97, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T00:28:43", + "duration": 27000000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-06-15T07:28:43Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T00:28:43", + "duration": 10877000, + "expectedDuration": 27000000, + "percent": 0.65, + "rate": 0.97, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T00:28:43", + "duration": 27000000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-06-15T07:28:43Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T03:30:00", + "duration": 27000000, + "percent": 0.65, + "rate": 0.87, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T03:30:00", + "duration": 27000000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-06-15T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T03:30:00", + "duration": 7200000, + "expectedDuration": 27000000, + "percent": 0.65, + "rate": 0.87, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T03:30:00", + "duration": 27000000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-06-15T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T05:30:00", + "duration": 27000000, + "percent": 0.65, + "rate": 1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T05:30:00", + "duration": 27000000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-06-15T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T05:30:00", + "duration": 8923000, + "expectedDuration": 27000000, + "percent": 0.65, + "rate": 1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T05:30:00", + "duration": 27000000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-06-15T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T07:58:43", + "duration": 1877000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T12:00:00", + "duration": 11186000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T15:06:26", + "duration": 10709000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T18:04:55", + "duration": 14105000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T08:30:00", + "duration": 7555000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T10:35:55", + "duration": 27000000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T10:35:55", + "duration": 27000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-06-18T17:35:55Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T10:35:55", + "duration": 5045000, + "expectedDuration": 27000000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T10:35:55", + "duration": 27000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-06-18T17:35:55Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T12:00:00", + "duration": 27000000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T12:00:00", + "duration": 27000000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-06-18T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T12:00:00", + "duration": 21600000, + "expectedDuration": 27000000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T12:00:00", + "duration": 27000000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-06-18T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T18:00:00", + "duration": 27000000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T18:00:00", + "duration": 27000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-06-19T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T18:00:00", + "duration": 354000, + "expectedDuration": 27000000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T18:00:00", + "duration": 27000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-06-19T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T18:05:54", + "duration": 6111000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T19:47:45", + "duration": 18000000, + "percent": 0.85, + "rate": 0.97, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T19:47:45", + "duration": 18000000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-06-19T02:47:45Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T19:47:45", + "duration": 7935000, + "expectedDuration": 18000000, + "percent": 0.85, + "rate": 0.97, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T19:47:45", + "duration": 18000000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-06-19T02:47:45Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T22:00:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.23, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T22:00:00", + "duration": 18000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-06-19T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T22:00:00", + "duration": 7200000, + "expectedDuration": 18000000, + "percent": 0.85, + "rate": 1.23, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T22:00:00", + "duration": 18000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-06-19T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T00:00:00", + "duration": 17880000, + "percent": 0.85, + "rate": 1.27, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T00:00:00", + "duration": 17880000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-06-19T07:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T00:00:00", + "duration": 2696000, + "expectedDuration": 17880000, + "percent": 0.85, + "rate": 1.27, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T00:00:00", + "duration": 17880000, + "rate": 1.49, + "scheduleName": "basal 3", + "time": "2018-06-19T07:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T00:44:56", + "duration": 112000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T00:46:48", + "duration": 9792000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T18:00:00", + "duration": 10769000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T20:59:29", + "duration": 3631000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T08:30:00", + "duration": 10621000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T11:27:01", + "duration": 25200000, + "percent": 0.8, + "rate": 1.12, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T11:27:01", + "duration": 25200000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-06-21T18:27:01Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T11:27:01", + "duration": 1979000, + "expectedDuration": 25200000, + "percent": 0.8, + "rate": 1.12, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T11:27:01", + "duration": 25200000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-06-21T18:27:01Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T12:00:00", + "duration": 14160000, + "percent": 0.8, + "rate": 0.48, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T12:00:00", + "duration": 14160000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-06-21T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T12:00:00", + "duration": 12135000, + "expectedDuration": 14160000, + "percent": 0.8, + "rate": 0.48, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T12:00:00", + "duration": 14160000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-06-21T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T15:22:15", + "duration": 52000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T18:23:07", + "duration": 13013000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T22:00:00", + "duration": 6238000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T23:43:58", + "duration": 870000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T23:58:28", + "duration": 92000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T00:00:00", + "duration": 9249000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T02:34:09", + "duration": 9000000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T02:34:09", + "duration": 9000000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-06-24T06:34:09Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T02:34:09", + "duration": 3351000, + "expectedDuration": 9000000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T02:34:09", + "duration": 9000000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-06-24T06:34:09Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T03:30:00", + "duration": 9000000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T03:30:00", + "duration": 9000000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-06-24T07:30:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T03:30:00", + "duration": 5649000, + "expectedDuration": 9000000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T03:30:00", + "duration": 9000000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-06-24T07:30:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T05:04:09", + "duration": 1551000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T08:30:00", + "duration": 6845000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T10:24:05", + "duration": 10800000, + "percent": 1.35, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T10:24:05", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-06-24T14:24:05Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T10:24:05", + "duration": 5755000, + "expectedDuration": 10800000, + "percent": 1.35, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T10:24:05", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-06-24T14:24:05Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T12:00:00", + "duration": 10800000, + "percent": 1.35, + "rate": 0.81, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T12:00:00", + "duration": 10800000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-06-24T16:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T12:00:00", + "duration": 5045000, + "expectedDuration": 10800000, + "percent": 1.35, + "rate": 0.81, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T12:00:00", + "duration": 10800000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-06-24T16:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T13:24:05", + "duration": 16555000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T05:30:00", + "duration": 8167000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T07:46:07", + "duration": 5319000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T09:14:46", + "duration": 9914000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T22:00:00", + "duration": 2939000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T22:48:59", + "duration": 3600000, + "percent": 0.85, + "rate": 1.19, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T22:48:59", + "duration": 3600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-06-26T02:48:59Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T23:48:59", + "duration": 661000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T00:00:00", + "duration": 10930000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T03:02:10", + "duration": 56000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T00:03:06", + "duration": 12414000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T12:00:00", + "duration": 16156000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T16:29:16", + "duration": 5400000, + "percent": 1.4, + "rate": 0.84, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T16:29:16", + "duration": 5400000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-06-27T23:29:16Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T17:59:16", + "duration": 44000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T12:00:00", + "duration": 7901000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T14:11:41", + "duration": 1866000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T14:42:47", + "duration": 11833000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T08:30:00", + "duration": 7554000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T10:35:54", + "duration": 27000000, + "percent": 0.85, + "rate": 1.19, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T10:35:54", + "duration": 27000000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-06-29T17:35:54Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T10:35:54", + "duration": 5046000, + "expectedDuration": 27000000, + "percent": 0.85, + "rate": 1.19, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T10:35:54", + "duration": 27000000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-06-29T17:35:54Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T12:00:00", + "duration": 27000000, + "percent": 0.85, + "rate": 0.51, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T12:00:00", + "duration": 27000000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-06-29T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T12:00:00", + "duration": 21600000, + "expectedDuration": 27000000, + "percent": 0.85, + "rate": 0.51, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T12:00:00", + "duration": 27000000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-06-29T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T18:00:00", + "duration": 27000000, + "percent": 0.85, + "rate": 0.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T18:00:00", + "duration": 27000000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-06-30T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T18:00:00", + "duration": 354000, + "expectedDuration": 27000000, + "percent": 0.85, + "rate": 0.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T18:00:00", + "duration": 27000000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-06-30T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T18:05:54", + "duration": 14046000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T22:00:00", + "duration": 5283000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T23:28:03", + "duration": 3855000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T00:32:18", + "duration": 10662000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T18:00:00", + "duration": 6951000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T19:55:51", + "duration": 7449000, + "rate": 1, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T22:00:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T05:30:00", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T08:30:00", + "duration": 10564000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T11:26:04", + "duration": 139000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T11:28:23", + "duration": 1897000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T00:00:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T03:30:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T00:00:00", + "duration": 11060000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:04:20", + "duration": 21600000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:04:20", + "duration": 21600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-07-03T10:04:20Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:04:20", + "duration": 1540000, + "expectedDuration": 21600000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:04:20", + "duration": 21600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-07-03T10:04:20Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:30:00", + "duration": 21600000, + "percent": 0.75, + "rate": 0.93, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:30:00", + "duration": 21600000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-07-03T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:30:00", + "duration": 7200000, + "expectedDuration": 21600000, + "percent": 0.75, + "rate": 0.93, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:30:00", + "duration": 21600000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-07-03T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T05:30:00", + "duration": 19560000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T05:30:00", + "duration": 19560000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-07-03T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T05:30:00", + "duration": 10631000, + "expectedDuration": 19560000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T05:30:00", + "duration": 19560000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-07-03T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T08:27:11", + "duration": 10538000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T11:22:49", + "duration": 2231000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T00:00:00", + "duration": 10459000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T02:54:19", + "duration": 7200000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T02:54:19", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-07-04T09:54:19Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T02:54:19", + "duration": 2141000, + "expectedDuration": 7200000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T02:54:19", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-07-04T09:54:19Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T03:30:00", + "duration": 7200000, + "percent": 0.75, + "rate": 0.93, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T03:30:00", + "duration": 7200000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-07-04T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T03:30:00", + "duration": 5059000, + "expectedDuration": 7200000, + "percent": 0.75, + "rate": 0.93, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T03:30:00", + "duration": 7200000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-07-04T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T04:54:19", + "duration": 2141000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T00:00:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T03:30:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T00:00:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T03:30:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T18:00:00", + "duration": 4501000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T19:15:01", + "duration": 442000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T19:22:23", + "duration": 9457000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T00:00:00", + "duration": 9207000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T02:33:27", + "duration": 3600000, + "percent": 1.35, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T02:33:27", + "duration": 3600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-07-07T09:33:27Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T02:33:27", + "duration": 3393000, + "expectedDuration": 3600000, + "percent": 1.35, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T02:33:27", + "duration": 3600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-07-07T09:33:27Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T03:30:00", + "duration": 3600000, + "percent": 1.35, + "rate": 1.68, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T03:30:00", + "duration": 3600000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-07-07T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T03:30:00", + "duration": 207000, + "expectedDuration": 3600000, + "percent": 1.35, + "rate": 1.68, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T03:30:00", + "duration": 3600000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-07-07T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T03:33:27", + "duration": 6993000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T00:00:00", + "duration": 7931000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T02:12:11", + "duration": 1802000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T02:42:13", + "duration": 2867000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T00:00:00", + "duration": 1644000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T00:27:24", + "duration": 387000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T00:33:51", + "duration": 10569000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T05:30:00", + "duration": 11850000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T08:47:30", + "duration": 7734000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T10:56:24", + "duration": 3816000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T12:00:00", + "duration": 11503000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T15:11:43", + "duration": 238000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T15:15:41", + "duration": 9859000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T00:00:00", + "duration": 11695000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:14:55", + "duration": 18000000, + "percent": 0.85, + "rate": 1.1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:14:55", + "duration": 18000000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-07-15T10:14:55Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:14:55", + "duration": 905000, + "expectedDuration": 18000000, + "percent": 0.85, + "rate": 1.1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:14:55", + "duration": 18000000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-07-15T10:14:55Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:30:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.02, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:30:00", + "duration": 18000000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-07-15T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:30:00", + "duration": 7200000, + "expectedDuration": 18000000, + "percent": 0.85, + "rate": 1.02, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:30:00", + "duration": 18000000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-07-15T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T05:30:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T05:30:00", + "duration": 18000000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-07-15T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T05:30:00", + "duration": 9895000, + "expectedDuration": 18000000, + "percent": 0.85, + "rate": 1.1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T05:30:00", + "duration": 18000000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-07-15T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T08:14:55", + "duration": 905000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T08:30:00", + "duration": 4149000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T09:39:09", + "duration": 6405000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T11:25:54", + "duration": 2046000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T12:00:00", + "duration": 10914000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T15:01:54", + "duration": 3600000, + "percent": 1.25, + "rate": 0.56, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T15:01:54", + "duration": 3600000, + "rate": 0.45, + "scheduleName": "basal 3", + "time": "2018-07-17T22:01:54Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T16:01:54", + "duration": 7086000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T12:00:00", + "duration": 14774000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T16:06:14", + "duration": 789000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T16:19:23", + "duration": 6037000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T18:00:00", + "duration": 5447000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T19:30:47", + "duration": 10800000, + "percent": 1.15, + "rate": 1.03, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T19:30:47", + "duration": 10800000, + "rate": 0.9, + "scheduleName": "basal 3", + "time": "2018-07-20T02:30:47Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T19:30:47", + "duration": 8953000, + "expectedDuration": 10800000, + "percent": 1.15, + "rate": 1.03, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T19:30:47", + "duration": 10800000, + "rate": 0.9, + "scheduleName": "basal 3", + "time": "2018-07-20T02:30:47Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T22:00:00", + "duration": 10800000, + "percent": 1.15, + "rate": 1.43, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T22:00:00", + "duration": 10800000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-07-20T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T22:00:00", + "duration": 1847000, + "expectedDuration": 10800000, + "percent": 1.15, + "rate": 1.43, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T22:00:00", + "duration": 10800000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-07-20T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T22:30:47", + "duration": 5353000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T00:00:00", + "duration": 7351000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T02:02:31", + "duration": 5400000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T02:02:31", + "duration": 5400000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-07-22T09:02:31Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T02:02:31", + "duration": 5249000, + "expectedDuration": 5400000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T02:02:31", + "duration": 5400000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-07-22T09:02:31Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T03:30:00", + "duration": 5400000, + "percent": 0.8, + "rate": 0.96, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T03:30:00", + "duration": 5400000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-07-22T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T03:30:00", + "duration": 151000, + "expectedDuration": 5400000, + "percent": 0.8, + "rate": 0.96, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T03:30:00", + "duration": 5400000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-07-22T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T03:32:31", + "duration": 7049000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T00:00:00", + "duration": 829000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T00:13:49", + "duration": 2232000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T00:51:01", + "duration": 9539000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T08:30:00", + "duration": 1596000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T08:56:36", + "duration": 882000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T09:11:18", + "duration": 10122000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T18:00:00", + "duration": 124000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T18:02:04", + "duration": 5400000, + "percent": 0.85, + "rate": 0.76, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T18:02:04", + "duration": 5400000, + "rate": 0.89, + "scheduleName": "basal 3", + "time": "2018-07-27T01:02:04Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T19:32:04", + "duration": 8876000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T00:00:00", + "duration": 860000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T00:14:20", + "duration": 2644000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T00:58:24", + "duration": 9096000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T18:00:00", + "duration": 1335000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T18:22:15", + "duration": 5400000, + "percent": 0.4, + "rate": 0.36, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T18:22:15", + "duration": 5400000, + "rate": 0.9, + "scheduleName": "basal 3", + "time": "2018-07-31T01:22:15Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T19:52:15", + "duration": 7665000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T00:00:00", + "duration": 7906000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T02:11:46", + "duration": 21445000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T08:09:11", + "duration": 1249000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T00:00:00", + "duration": 6044000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T01:40:44", + "duration": 5880000, + "percent": 0.85, + "rate": 1.1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T01:40:44", + "duration": 5880000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-08-03T08:40:44Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T01:40:44", + "duration": 5867000, + "expectedDuration": 5880000, + "percent": 0.85, + "rate": 1.1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T01:40:44", + "duration": 5880000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-08-03T08:40:44Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:18:31", + "duration": 9000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:18:40", + "duration": 7200000, + "percent": 0.7, + "rate": 0.91, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:18:40", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-08-03T10:18:40Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:18:40", + "duration": 680000, + "expectedDuration": 7200000, + "percent": 0.7, + "rate": 0.91, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:18:40", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-08-03T10:18:40Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:30:00", + "duration": 7200000, + "percent": 0.7, + "rate": 0.84, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-08-03T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:30:00", + "duration": 6520000, + "expectedDuration": 7200000, + "percent": 0.7, + "rate": 0.84, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-08-03T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T05:18:40", + "duration": 680000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T12:00:00", + "duration": 8453000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T14:20:53", + "duration": 326000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T14:26:19", + "duration": 12821000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T12:00:00", + "duration": 18803000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T17:13:23", + "duration": 7200000, + "percent": 1.25, + "rate": 0.56, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T17:13:23", + "duration": 7200000, + "rate": 0.45, + "scheduleName": "basal 3", + "time": "2018-08-06T00:13:23Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T17:13:23", + "duration": 2797000, + "expectedDuration": 7200000, + "percent": 1.25, + "rate": 0.56, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T17:13:23", + "duration": 7200000, + "rate": 0.45, + "scheduleName": "basal 3", + "time": "2018-08-06T00:13:23Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T18:00:00", + "duration": 7200000, + "percent": 1.25, + "rate": 1.12, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T18:00:00", + "duration": 7200000, + "rate": 0.9, + "scheduleName": "basal 3", + "time": "2018-08-06T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T18:00:00", + "duration": 4403000, + "expectedDuration": 7200000, + "percent": 1.25, + "rate": 1.12, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T18:00:00", + "duration": 7200000, + "rate": 0.9, + "scheduleName": "basal 3", + "time": "2018-08-06T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T19:13:23", + "duration": 9106000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T21:45:09", + "duration": 251000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T21:49:20", + "duration": 640000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T05:30:00", + "duration": 9183000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T08:03:03", + "duration": 1617000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T03:30:00", + "duration": 5472000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T05:01:12", + "duration": 180000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T05:04:12", + "duration": 1548000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T18:00:00", + "duration": 13178000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T21:39:38", + "duration": 3600000, + "percent": 1.15, + "rate": 1.2, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T21:39:38", + "duration": 3600000, + "rate": 1.04, + "scheduleName": "basal 3", + "time": "2018-08-12T04:39:38Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T21:39:38", + "duration": 1222000, + "expectedDuration": 3600000, + "percent": 1.15, + "rate": 1.2, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T21:39:38", + "duration": 3600000, + "rate": 1.04, + "scheduleName": "basal 3", + "time": "2018-08-12T04:39:38Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T22:00:00", + "duration": 3600000, + "percent": 1.15, + "rate": 1.61, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T22:00:00", + "duration": 3600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-08-12T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T22:00:00", + "duration": 2378000, + "expectedDuration": 3600000, + "percent": 1.15, + "rate": 1.61, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T22:00:00", + "duration": 3600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-08-12T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T22:39:38", + "duration": 4822000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T12:00:00", + "duration": 4236000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T13:10:36", + "duration": 3620000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T14:10:56", + "duration": 3631000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T15:11:27", + "duration": 600000, + "percent": 0.8, + "rate": 0.48, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T15:11:27", + "duration": 600000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-08-12T22:11:27Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T15:11:27", + "duration": 588000, + "expectedDuration": 600000, + "percent": 0.8, + "rate": 0.48, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T15:11:27", + "duration": 600000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-08-12T22:11:27Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T15:21:15", + "duration": 7934000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T17:33:29", + "duration": 1591000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T00:00:00", + "duration": 8499000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T02:21:39", + "duration": 16200000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T02:21:39", + "duration": 16200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-08-14T09:21:39Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T02:21:39", + "duration": 4101000, + "expectedDuration": 16200000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T02:21:39", + "duration": 16200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-08-14T09:21:39Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T03:30:00", + "duration": 16200000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T03:30:00", + "duration": 16200000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-08-14T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T03:30:00", + "duration": 7200000, + "expectedDuration": 16200000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T03:30:00", + "duration": 16200000, + "rate": 1.35, + "scheduleName": "basal 3", + "time": "2018-08-14T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T05:30:00", + "duration": 16200000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T05:30:00", + "duration": 16200000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-08-14T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T05:30:00", + "duration": 4899000, + "expectedDuration": 16200000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T05:30:00", + "duration": 16200000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-08-14T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T06:51:39", + "duration": 5901000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T18:00:00", + "duration": 3812000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T19:03:32", + "duration": 6060000, + "percent": 0.75, + "rate": 0.78, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T19:03:32", + "duration": 6060000, + "rate": 1.04, + "scheduleName": "basal 3", + "time": "2018-08-15T02:03:32Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T19:03:32", + "duration": 6031000, + "expectedDuration": 6060000, + "percent": 0.75, + "rate": 0.78, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T19:03:32", + "duration": 6060000, + "rate": 1.04, + "scheduleName": "basal 3", + "time": "2018-08-15T02:03:32Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T20:44:03", + "duration": 9000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T20:44:12", + "duration": 5400000, + "percent": 0.65, + "rate": 0.68, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T20:44:12", + "duration": 5400000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-08-15T03:44:12Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T20:44:12", + "duration": 4548000, + "expectedDuration": 5400000, + "percent": 0.65, + "rate": 0.68, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T20:44:12", + "duration": 5400000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-08-15T03:44:12Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T22:00:00", + "duration": 5400000, + "percent": 0.65, + "rate": 0.91, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T22:00:00", + "duration": 5400000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-08-15T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T22:00:00", + "duration": 852000, + "expectedDuration": 5400000, + "percent": 0.65, + "rate": 0.91, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T22:00:00", + "duration": 5400000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-08-15T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T22:14:12", + "duration": 6348000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T08:30:00", + "duration": 7596000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T10:36:36", + "duration": 5004000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T18:00:00", + "duration": 57000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T18:00:57", + "duration": 10800000, + "percent": 0.19999999999999996, + "rate": 0.18, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T18:00:57", + "duration": 10800000, + "rate": 0.9, + "scheduleName": "basal 3", + "time": "2018-08-16T01:00:57Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T21:00:57", + "duration": 2953000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T21:50:10", + "duration": 240000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T21:54:10", + "duration": 350000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T05:30:00", + "duration": 1539000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T05:55:39", + "duration": 255000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T05:59:54", + "duration": 9006000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T12:00:00", + "duration": 19916000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T17:31:56", + "duration": 9000000, + "percent": 0.6, + "rate": 0.27, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T17:31:56", + "duration": 9000000, + "rate": 0.45, + "scheduleName": "basal 3", + "time": "2018-08-21T00:31:56Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T17:31:56", + "duration": 1684000, + "expectedDuration": 9000000, + "percent": 0.6, + "rate": 0.27, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T17:31:56", + "duration": 9000000, + "rate": 0.45, + "scheduleName": "basal 3", + "time": "2018-08-21T00:31:56Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T18:00:00", + "duration": 9000000, + "percent": 0.6, + "rate": 0.54, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T18:00:00", + "duration": 9000000, + "rate": 0.9, + "scheduleName": "basal 3", + "time": "2018-08-21T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T18:00:00", + "duration": 7316000, + "expectedDuration": 9000000, + "percent": 0.6, + "rate": 0.54, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T18:00:00", + "duration": 9000000, + "rate": 0.9, + "scheduleName": "basal 3", + "time": "2018-08-21T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T20:01:56", + "duration": 7084000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T12:00:00", + "duration": 12721000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T15:32:01", + "duration": 1800000, + "percent": 0.7, + "rate": 0.31, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T15:32:01", + "duration": 1800000, + "rate": 0.44, + "scheduleName": "basal 3", + "time": "2018-08-21T22:32:01Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T16:02:01", + "duration": 7079000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T12:00:00", + "duration": 6854000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T13:54:14", + "duration": 473000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T14:02:07", + "duration": 14273000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T00:00:00", + "duration": 11831000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:17:11", + "duration": 25200000, + "percent": 0.75, + "rate": 0.97, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:17:11", + "duration": 25200000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-08-23T10:17:11Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:17:11", + "duration": 769000, + "expectedDuration": 25200000, + "percent": 0.75, + "rate": 0.97, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:17:11", + "duration": 25200000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-08-23T10:17:11Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:30:00", + "duration": 25200000, + "percent": 0.75, + "rate": 0.9, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:30:00", + "duration": 25200000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-08-23T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:30:00", + "duration": 7200000, + "expectedDuration": 25200000, + "percent": 0.75, + "rate": 0.9, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:30:00", + "duration": 25200000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-08-23T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T05:30:00", + "duration": 25200000, + "percent": 0.75, + "rate": 0.97, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T05:30:00", + "duration": 25200000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-08-23T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T05:30:00", + "duration": 10800000, + "expectedDuration": 25200000, + "percent": 0.75, + "rate": 0.97, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T05:30:00", + "duration": 25200000, + "rate": 1.29, + "scheduleName": "basal 3", + "time": "2018-08-23T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T08:30:00", + "duration": 25200000, + "percent": 0.75, + "rate": 0.93, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T08:30:00", + "duration": 25200000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-08-23T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T08:30:00", + "duration": 6431000, + "expectedDuration": 25200000, + "percent": 0.75, + "rate": 0.93, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T08:30:00", + "duration": 25200000, + "rate": 1.24, + "scheduleName": "basal 3", + "time": "2018-08-23T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T10:17:11", + "duration": 6169000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T00:00:00", + "duration": 7034000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T01:57:14", + "duration": 25200000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T01:57:14", + "duration": 25200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-08-24T08:57:14Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T01:57:14", + "duration": 5566000, + "expectedDuration": 25200000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T01:57:14", + "duration": 25200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-08-24T08:57:14Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T03:30:00", + "duration": 25200000, + "percent": 0.8, + "rate": 0.96, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T03:30:00", + "duration": 25200000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-08-24T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T03:30:00", + "duration": 7200000, + "expectedDuration": 25200000, + "percent": 0.8, + "rate": 0.96, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T03:30:00", + "duration": 25200000, + "rate": 1.2, + "scheduleName": "basal 3", + "time": "2018-08-24T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T05:30:00", + "duration": 25200000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T05:30:00", + "duration": 25200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-08-24T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T05:30:00", + "duration": 10800000, + "expectedDuration": 25200000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T05:30:00", + "duration": 25200000, + "rate": 1.3, + "scheduleName": "basal 3", + "time": "2018-08-24T12:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T08:30:00", + "duration": 25200000, + "percent": 0.8, + "rate": 1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T08:30:00", + "duration": 25200000, + "rate": 1.25, + "scheduleName": "basal 3", + "time": "2018-08-24T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T08:30:00", + "duration": 1634000, + "expectedDuration": 25200000, + "percent": 0.8, + "rate": 1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T08:30:00", + "duration": 25200000, + "rate": 1.25, + "scheduleName": "basal 3", + "time": "2018-08-24T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T08:57:14", + "duration": 10966000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T12:00:00", + "duration": 8532000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T14:22:12", + "duration": 7200000, + "percent": 0.30000000000000004, + "rate": 0.13, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T14:22:12", + "duration": 7200000, + "rate": 0.43, + "scheduleName": "basal 3", + "time": "2018-08-24T21:22:12Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T16:22:12", + "duration": 5868000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T18:00:00", + "duration": 14095000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T21:54:55", + "duration": 280000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T21:59:35", + "duration": 25000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T03:30:00", + "duration": 6075000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T05:11:15", + "duration": 397000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T05:17:52", + "duration": 728000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T12:00:00", + "duration": 4392000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T13:13:12", + "duration": 17592000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T18:06:24", + "duration": 14016000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T08:30:00", + "duration": 9169000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T11:02:49", + "duration": 3431000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T05:30:00", + "duration": 4177000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T06:39:37", + "duration": 10025000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T09:26:42", + "duration": 9198000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T12:00:00", + "duration": 19217000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T17:20:17", + "duration": 6688000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T19:11:45", + "duration": 10095000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T00:00:00", + "duration": 1827000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T00:30:27", + "duration": 1374000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T00:53:21", + "duration": 9399000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T08:30:00", + "duration": 2264000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T09:07:44", + "duration": 7415000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T11:11:19", + "duration": 1593000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T11:37:52", + "duration": 5400000, + "percent": 1.35, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T11:37:52", + "duration": 5400000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-09-14T18:37:52Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T11:37:52", + "duration": 1328000, + "expectedDuration": 5400000, + "percent": 1.35, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T11:37:52", + "duration": 5400000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-09-14T18:37:52Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T12:00:00", + "duration": 5400000, + "percent": 1.35, + "rate": 0.81, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T12:00:00", + "duration": 5400000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-14T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T12:00:00", + "duration": 4072000, + "expectedDuration": 5400000, + "percent": 1.35, + "rate": 0.81, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T12:00:00", + "duration": 5400000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-14T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T13:07:52", + "duration": 17528000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T12:00:00", + "duration": 142000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T12:02:22", + "duration": 3600000, + "percent": 0.7, + "rate": 0.42, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T12:02:22", + "duration": 3600000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-15T19:02:22Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T13:02:22", + "duration": 17858000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T08:30:00", + "duration": 5863000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T10:07:43", + "duration": 5400000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T10:07:43", + "duration": 5400000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-09-16T17:07:43Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T11:37:43", + "duration": 1337000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T18:00:00", + "duration": 4181000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T19:09:41", + "duration": 3495000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T20:07:56", + "duration": 6724000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T12:00:00", + "duration": 5103000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T13:25:03", + "duration": 76000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T13:26:19", + "duration": 16421000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T18:00:00", + "duration": 13638000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T21:47:18", + "duration": 533000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T21:56:11", + "duration": 229000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T18:00:00", + "duration": 2999000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T18:49:59", + "duration": 3600000, + "percent": 1.45, + "rate": 1.52, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T18:49:59", + "duration": 3600000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-09-21T01:49:59Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T19:49:59", + "duration": 7801000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T00:00:00", + "duration": 2319000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T00:38:39", + "duration": 7200000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T00:38:39", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-09-21T07:38:39Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T02:38:39", + "duration": 3081000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T00:00:00", + "duration": 1518000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T00:25:18", + "duration": 3600000, + "percent": 0.7, + "rate": 1.05, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T00:25:18", + "duration": 3600000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-09-22T07:25:18Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T01:25:18", + "duration": 7482000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T05:30:00", + "duration": 1230000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T05:50:30", + "duration": 18830000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T11:04:20", + "duration": 3340000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T12:00:00", + "duration": 19246000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T17:20:46", + "duration": 7200000, + "percent": 1.7, + "rate": 1.02, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T17:20:46", + "duration": 7200000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-24T00:20:46Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T17:20:46", + "duration": 2354000, + "expectedDuration": 7200000, + "percent": 1.7, + "rate": 1.02, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T17:20:46", + "duration": 7200000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-24T00:20:46Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T18:00:00", + "duration": 7200000, + "percent": 1.7, + "rate": 1.78, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T18:00:00", + "duration": 7200000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-09-24T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T18:00:00", + "duration": 4846000, + "expectedDuration": 7200000, + "percent": 1.7, + "rate": 1.78, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T18:00:00", + "duration": 7200000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-09-24T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T19:20:46", + "duration": 9554000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T08:30:00", + "duration": 2085000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T09:04:45", + "duration": 4217000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T10:15:02", + "duration": 6298000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T12:00:00", + "duration": 17944000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T16:59:04", + "duration": 3600000, + "percent": 1.65, + "rate": 0.99, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T16:59:04", + "duration": 3600000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-26T23:59:04Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T17:59:04", + "duration": 56000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T18:00:00", + "duration": 5666000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T19:34:26", + "duration": 5400000, + "percent": 1.9, + "rate": 1.99, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T19:34:26", + "duration": 5400000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-09-27T02:34:26Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T21:04:26", + "duration": 3334000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T00:00:00", + "duration": 2082000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T00:34:42", + "duration": 3600000, + "percent": 1.35, + "rate": 2.02, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T00:34:42", + "duration": 3600000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-09-27T07:34:42Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T01:34:42", + "duration": 6918000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T12:00:00", + "duration": 5752000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T13:35:52", + "duration": 204000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T13:39:16", + "duration": 5345000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T15:08:21", + "duration": 5400000, + "percent": 1.55, + "rate": 0.93, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T15:08:21", + "duration": 5400000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-27T22:08:21Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T16:38:21", + "duration": 4899000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T18:00:00", + "duration": 6720000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T19:52:00", + "duration": 645000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T20:02:45", + "duration": 7035000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T05:30:00", + "duration": 9805000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:13:25", + "duration": 5400000, + "percent": 1.5, + "rate": 2.32, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:13:25", + "duration": 5400000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-09-28T15:13:25Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:13:25", + "duration": 995000, + "expectedDuration": 5400000, + "percent": 1.5, + "rate": 2.32, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:13:25", + "duration": 5400000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-09-28T15:13:25Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:30:00", + "duration": 5400000, + "percent": 1.5, + "rate": 2.1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:30:00", + "duration": 5400000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-09-28T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:30:00", + "duration": 4405000, + "expectedDuration": 5400000, + "percent": 1.5, + "rate": 2.1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:30:00", + "duration": 5400000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-09-28T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T09:43:25", + "duration": 8195000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T12:00:00", + "duration": 2532000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T12:42:12", + "duration": 4620000, + "percent": 1.4, + "rate": 0.84, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T12:42:12", + "duration": 4620000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-28T19:42:12Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T12:42:12", + "duration": 4596000, + "expectedDuration": 4620000, + "percent": 1.4, + "rate": 0.84, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T12:42:12", + "duration": 4620000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-28T19:42:12Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T13:58:48", + "duration": 14000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T13:59:02", + "duration": 5400000, + "percent": 1.55, + "rate": 0.93, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T13:59:02", + "duration": 5400000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-28T20:59:02Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T15:29:02", + "duration": 6819000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T17:22:41", + "duration": 7200000, + "percent": 1.35, + "rate": 0.81, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T17:22:41", + "duration": 7200000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-29T00:22:41Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T17:22:41", + "duration": 2239000, + "expectedDuration": 7200000, + "percent": 1.35, + "rate": 0.81, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T17:22:41", + "duration": 7200000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-29T00:22:41Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T18:00:00", + "duration": 7200000, + "percent": 1.35, + "rate": 1.41, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T18:00:00", + "duration": 7200000, + "rate": 1.04, + "scheduleName": "basal 3", + "time": "2018-09-29T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T18:00:00", + "duration": 4961000, + "expectedDuration": 7200000, + "percent": 1.35, + "rate": 1.41, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T18:00:00", + "duration": 7200000, + "rate": 1.04, + "scheduleName": "basal 3", + "time": "2018-09-29T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T19:22:41", + "duration": 9439000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T00:00:00", + "duration": 9113000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T02:31:53", + "duration": 5400000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T02:31:53", + "duration": 5400000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-09-29T09:31:53Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T02:31:53", + "duration": 3487000, + "expectedDuration": 5400000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T02:31:53", + "duration": 5400000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-09-29T09:31:53Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T03:30:00", + "duration": 5400000, + "percent": 1.25, + "rate": 1.68, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T03:30:00", + "duration": 5400000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-09-29T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T03:30:00", + "duration": 1913000, + "expectedDuration": 5400000, + "percent": 1.25, + "rate": 1.68, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T03:30:00", + "duration": 5400000, + "rate": 1.34, + "scheduleName": "basal 3", + "time": "2018-09-29T10:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T04:01:53", + "duration": 5287000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T08:30:00", + "duration": 4914000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T09:51:54", + "duration": 9000000, + "percent": 0.8, + "rate": 1.12, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T09:51:54", + "duration": 9000000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-09-29T16:51:54Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T09:51:54", + "duration": 7686000, + "expectedDuration": 9000000, + "percent": 0.8, + "rate": 1.12, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T09:51:54", + "duration": 9000000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-09-29T16:51:54Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T12:00:00", + "duration": 9000000, + "percent": 0.8, + "rate": 0.48, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T12:00:00", + "duration": 9000000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-29T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T12:00:00", + "duration": 1314000, + "expectedDuration": 9000000, + "percent": 0.8, + "rate": 0.48, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T12:00:00", + "duration": 9000000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-29T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T12:21:54", + "duration": 20286000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T18:00:00", + "duration": 1416000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T18:23:36", + "duration": 10800000, + "percent": 1.5, + "rate": 1.57, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T18:23:36", + "duration": 10800000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-09-30T01:23:36Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T21:23:36", + "duration": 2184000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T08:30:00", + "duration": 3040000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T09:20:40", + "duration": 3159000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T10:13:19", + "duration": 6401000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T12:00:00", + "duration": 4788000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T13:19:48", + "duration": 7200000, + "percent": 1.45, + "rate": 0.87, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T13:19:48", + "duration": 7200000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-30T20:19:48Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T15:19:48", + "duration": 4339000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T16:32:07", + "duration": 7200000, + "percent": 1.5, + "rate": 0.9, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T16:32:07", + "duration": 7200000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-30T23:32:07Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T16:32:07", + "duration": 5273000, + "expectedDuration": 7200000, + "percent": 1.5, + "rate": 0.9, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T16:32:07", + "duration": 7200000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-09-30T23:32:07Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T18:00:00", + "duration": 7200000, + "percent": 1.5, + "rate": 1.57, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T18:00:00", + "duration": 7200000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-10-01T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T18:00:00", + "duration": 1927000, + "expectedDuration": 7200000, + "percent": 1.5, + "rate": 1.57, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T18:00:00", + "duration": 7200000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-10-01T01:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T18:32:07", + "duration": 12473000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T18:00:00", + "duration": 4755000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T19:19:15", + "duration": 9000000, + "percent": 1.5, + "rate": 1.57, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T19:19:15", + "duration": 9000000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-10-02T02:19:15Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T21:49:15", + "duration": 645000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T18:00:00", + "duration": 12431000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T21:27:11", + "duration": 10800000, + "percent": 1.95, + "rate": 2.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T21:27:11", + "duration": 10800000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-10-03T04:27:11Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T21:27:11", + "duration": 1969000, + "expectedDuration": 10800000, + "percent": 1.95, + "rate": 2.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T21:27:11", + "duration": 10800000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-10-03T04:27:11Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T22:00:00", + "duration": 10800000, + "percent": 1.95, + "rate": 2.73, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T22:00:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-03T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T22:00:00", + "duration": 7200000, + "expectedDuration": 10800000, + "percent": 1.95, + "rate": 2.73, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T22:00:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-03T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T00:00:00", + "duration": 10800000, + "percent": 1.95, + "rate": 2.92, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T00:00:00", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-10-03T07:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T00:00:00", + "duration": 1631000, + "expectedDuration": 10800000, + "percent": 1.95, + "rate": 2.92, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T00:00:00", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3", + "time": "2018-10-03T07:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T00:27:11", + "duration": 10969000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T18:00:00", + "duration": 260000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T18:04:20", + "duration": 3314000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T18:59:34", + "duration": 7000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T18:59:41", + "duration": 45000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T19:00:26", + "duration": 10774000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T05:30:00", + "duration": 7859000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T07:40:59", + "duration": 36000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T07:41:35", + "duration": 2905000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T08:30:00", + "duration": 5764000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T10:06:04", + "duration": 7200000, + "percent": 1.25, + "rate": 1.75, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T10:06:04", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-04T17:06:04Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T10:06:04", + "duration": 6836000, + "expectedDuration": 7200000, + "percent": 1.25, + "rate": 1.75, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T10:06:04", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-04T17:06:04Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T12:00:00", + "duration": 7200000, + "percent": 1.25, + "rate": 0.75, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T12:00:00", + "duration": 7200000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-10-04T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T12:00:00", + "duration": 364000, + "expectedDuration": 7200000, + "percent": 1.25, + "rate": 0.75, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T12:00:00", + "duration": 7200000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-10-04T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T12:06:04", + "duration": 21236000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T08:30:00", + "duration": 11084000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T11:34:44", + "duration": 3600000, + "percent": 0.7, + "rate": 0.98, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T11:34:44", + "duration": 3600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-05T18:34:44Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T11:34:44", + "duration": 1516000, + "expectedDuration": 3600000, + "percent": 0.7, + "rate": 0.98, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T11:34:44", + "duration": 3600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-05T18:34:44Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T12:00:00", + "duration": 3600000, + "percent": 0.7, + "rate": 0.42, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T12:00:00", + "duration": 3600000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-10-05T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T12:00:00", + "duration": 2084000, + "expectedDuration": 3600000, + "percent": 0.7, + "rate": 0.42, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T12:00:00", + "duration": 3600000, + "rate": 0.6, + "scheduleName": "basal 3", + "time": "2018-10-05T19:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T12:34:44", + "duration": 19516000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T12:00:00", + "duration": 12872000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T15:34:32", + "duration": 4983000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T16:57:35", + "duration": 3745000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T18:00:00", + "duration": 5583000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T19:33:03", + "duration": 7200000, + "percent": 1.55, + "rate": 1.62, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T19:33:03", + "duration": 7200000, + "rate": 1.05, + "scheduleName": "basal 3", + "time": "2018-10-07T02:33:03Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T21:33:03", + "duration": 1617000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T00:00:00", + "duration": 2776000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T00:46:16", + "duration": 7200000, + "percent": 1.3, + "rate": 2.01, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T00:46:16", + "duration": 7200000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-10-07T07:46:16Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T02:46:16", + "duration": 2624000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T22:00:00", + "duration": 1978000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T22:32:58", + "duration": 14400000, + "percent": 1.75, + "rate": 2.45, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T22:32:58", + "duration": 14400000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-08T05:32:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T22:32:58", + "duration": 5222000, + "expectedDuration": 14400000, + "percent": 1.75, + "rate": 2.45, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T22:32:58", + "duration": 14400000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-08T05:32:58Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T00:00:00", + "duration": 14400000, + "percent": 1.75, + "rate": 2.71, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T00:00:00", + "duration": 14400000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-10-08T07:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T00:00:00", + "duration": 9178000, + "expectedDuration": 14400000, + "percent": 1.75, + "rate": 2.71, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T00:00:00", + "duration": 14400000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-10-08T07:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T02:32:58", + "duration": 3422000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T05:30:00", + "duration": 8216000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T07:46:56", + "duration": 670000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T07:58:06", + "duration": 9000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T07:58:15", + "duration": 3600000, + "percent": 1.45, + "rate": 2.24, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T07:58:15", + "duration": 3600000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-10-09T14:58:15Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T07:58:15", + "duration": 1905000, + "expectedDuration": 3600000, + "percent": 1.45, + "rate": 2.24, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T07:58:15", + "duration": 3600000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-10-09T14:58:15Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T08:30:00", + "duration": 3600000, + "percent": 1.45, + "rate": 2.03, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T08:30:00", + "duration": 3600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-09T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T08:30:00", + "duration": 1695000, + "expectedDuration": 3600000, + "percent": 1.45, + "rate": 2.03, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T08:30:00", + "duration": 3600000, + "rate": 1.4, + "scheduleName": "basal 3", + "time": "2018-10-09T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T08:58:15", + "duration": 10905000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T18:00:00", + "duration": 1977000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T18:32:57", + "duration": 4784000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T19:52:41", + "duration": 7639000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T08:30:00", + "duration": 993000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T08:46:33", + "duration": 11607000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T03:30:00", + "duration": 14251000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T07:27:31", + "duration": 3604000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T08:27:35", + "duration": 145000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T12:00:00", + "duration": 1528000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T12:25:28", + "duration": 5400000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T12:25:28", + "duration": 5400000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-10-12T19:25:28Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T12:25:28", + "duration": 5399000, + "expectedDuration": 5400000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T12:25:28", + "duration": 5400000, + "rate": 0.64, + "scheduleName": "basal 3", + "time": "2018-10-12T19:25:28Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T13:55:27", + "duration": 14673000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:00:00", + "duration": 887000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:14:47", + "duration": 60000, + "percent": 0.6, + "rate": 0.99, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:14:47", + "duration": 60000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-13T07:14:47Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:14:47", + "duration": 17000, + "expectedDuration": 60000, + "percent": 0.6, + "rate": 0.99, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:14:47", + "duration": 60000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-13T07:14:47Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:15:04", + "duration": 23000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:15:27", + "duration": 3147000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T01:07:54", + "duration": 435000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T04:15:09", + "duration": 14000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T04:15:23", + "duration": 9240000, + "percent": 0.65, + "rate": 1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T04:15:23", + "duration": 9240000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-10-13T08:15:23Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T04:15:23", + "duration": 9089000, + "expectedDuration": 9240000, + "percent": 0.65, + "rate": 1, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T04:15:23", + "duration": 9240000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-10-13T08:15:23Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T06:46:52", + "duration": 297000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T06:51:49", + "duration": 17000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T06:52:06", + "duration": 3600000, + "percent": 0.85, + "rate": 1.31, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T06:52:06", + "duration": 3600000, + "rate": 1.54, + "scheduleName": "basal 3", + "time": "2018-10-13T10:52:06Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T07:52:06", + "duration": 2274000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T18:00:00", + "duration": 10401000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T20:53:21", + "duration": 16200000, + "percent": 1.65, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T20:53:21", + "duration": 16200000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-14T00:53:21Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T20:53:21", + "duration": 3999000, + "expectedDuration": 16200000, + "percent": 1.65, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T20:53:21", + "duration": 16200000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-14T00:53:21Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T22:00:00", + "duration": 16200000, + "percent": 1.65, + "rate": 2.39, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T22:00:00", + "duration": 16200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-14T02:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T22:00:00", + "duration": 7200000, + "expectedDuration": 16200000, + "percent": 1.65, + "rate": 2.39, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T22:00:00", + "duration": 16200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-14T02:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T00:00:00", + "duration": 16200000, + "percent": 1.65, + "rate": 2.72, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T00:00:00", + "duration": 16200000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-14T04:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T00:00:00", + "duration": 5001000, + "expectedDuration": 16200000, + "percent": 1.65, + "rate": 2.72, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T00:00:00", + "duration": 16200000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-14T04:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T01:23:21", + "duration": 566000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T01:32:47", + "duration": 12600000, + "percent": 1.65, + "rate": 2.72, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T01:32:47", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-14T05:32:47Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T01:32:47", + "duration": 7033000, + "expectedDuration": 12600000, + "percent": 1.65, + "rate": 2.72, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T01:32:47", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-14T05:32:47Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T03:30:00", + "duration": 12600000, + "percent": 1.65, + "rate": 2.55, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T03:30:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-10-14T07:30:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T03:30:00", + "duration": 5567000, + "expectedDuration": 12600000, + "percent": 1.65, + "rate": 2.55, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T03:30:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-10-14T07:30:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T05:02:47", + "duration": 12433000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T12:00:00", + "duration": 18910000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T17:15:10", + "duration": 10800000, + "percent": 1.45, + "rate": 0.94, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T17:15:10", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-14T21:15:10Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T17:15:10", + "duration": 2690000, + "expectedDuration": 10800000, + "percent": 1.45, + "rate": 0.94, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T17:15:10", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-14T21:15:10Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T18:00:00", + "duration": 10800000, + "percent": 1.45, + "rate": 1.66, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T18:00:00", + "duration": 10800000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-10-14T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T18:00:00", + "duration": 8110000, + "expectedDuration": 10800000, + "percent": 1.45, + "rate": 1.66, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T18:00:00", + "duration": 10800000, + "rate": 1.14, + "scheduleName": "basal 3", + "time": "2018-10-14T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T20:15:10", + "duration": 6290000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T12:00:00", + "duration": 8739000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T14:25:39", + "duration": 1563000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T14:51:42", + "duration": 5877000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T16:29:39", + "duration": 10800000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T16:29:39", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-15T20:29:39Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T16:29:39", + "duration": 5421000, + "expectedDuration": 10800000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T16:29:39", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-15T20:29:39Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T18:00:00", + "duration": 10800000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T18:00:00", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-15T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T18:00:00", + "duration": 5379000, + "expectedDuration": 10800000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T18:00:00", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-15T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T19:29:39", + "duration": 9021000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T18:00:00", + "duration": 813000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T18:13:33", + "duration": 18000000, + "percent": 1.65, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T18:13:33", + "duration": 18000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-16T22:13:33Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T18:13:33", + "duration": 13587000, + "expectedDuration": 18000000, + "percent": 1.65, + "rate": 1.89, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T18:13:33", + "duration": 18000000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-16T22:13:33Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T22:00:00", + "duration": 18000000, + "percent": 1.65, + "rate": 2.39, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T22:00:00", + "duration": 18000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-17T02:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T22:00:00", + "duration": 4413000, + "expectedDuration": 18000000, + "percent": 1.65, + "rate": 2.39, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T22:00:00", + "duration": 18000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-17T02:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T23:13:33", + "duration": 2787000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T12:00:00", + "duration": 12800000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T15:33:20", + "duration": 256000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T15:37:36", + "duration": 8544000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T00:00:00", + "duration": 586000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T00:09:46", + "duration": 12600000, + "percent": 1.7, + "rate": 2.8, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T00:09:46", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-19T04:09:46Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T00:09:46", + "duration": 12014000, + "expectedDuration": 12600000, + "percent": 1.7, + "rate": 2.8, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T00:09:46", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-19T04:09:46Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T03:30:00", + "duration": 12600000, + "percent": 1.7, + "rate": 2.63, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T03:30:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-10-19T07:30:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T03:30:00", + "duration": 586000, + "expectedDuration": 12600000, + "percent": 1.7, + "rate": 2.63, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T03:30:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-10-19T07:30:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T03:39:46", + "duration": 17414000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T12:00:00", + "duration": 17302000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T16:48:22", + "duration": 7200000, + "percent": 1.6, + "rate": 1.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T16:48:22", + "duration": 7200000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-19T20:48:22Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T16:48:22", + "duration": 4298000, + "expectedDuration": 7200000, + "percent": 1.6, + "rate": 1.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T16:48:22", + "duration": 7200000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-19T20:48:22Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T18:00:00", + "duration": 7200000, + "percent": 1.6, + "rate": 1.84, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T18:00:00", + "duration": 7200000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-19T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T18:00:00", + "duration": 2902000, + "expectedDuration": 7200000, + "percent": 1.6, + "rate": 1.84, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T18:00:00", + "duration": 7200000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-19T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T18:48:22", + "duration": 11498000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T12:00:00", + "duration": 19646000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T17:27:26", + "duration": 10800000, + "percent": 1.75, + "rate": 1.13, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T17:27:26", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-20T21:27:26Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T17:27:26", + "duration": 1954000, + "expectedDuration": 10800000, + "percent": 1.75, + "rate": 1.13, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T17:27:26", + "duration": 10800000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-20T21:27:26Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T18:00:00", + "duration": 10800000, + "percent": 1.75, + "rate": 2.01, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T18:00:00", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-20T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T18:00:00", + "duration": 8846000, + "expectedDuration": 10800000, + "percent": 1.75, + "rate": 2.01, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T18:00:00", + "duration": 10800000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-20T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T20:27:26", + "duration": 5554000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T22:00:00", + "duration": 3002000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T22:50:02", + "duration": 416000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T22:56:58", + "duration": 3782000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T12:00:00", + "duration": 11357000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T15:09:17", + "duration": 12600000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T15:09:17", + "duration": 12600000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-22T19:09:17Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T15:09:17", + "duration": 10243000, + "expectedDuration": 12600000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T15:09:17", + "duration": 12600000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-22T19:09:17Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T18:00:00", + "duration": 12600000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T18:00:00", + "duration": 12600000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-22T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T18:00:00", + "duration": 2357000, + "expectedDuration": 12600000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T18:00:00", + "duration": 12600000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-22T22:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T18:39:17", + "duration": 12043000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T08:30:00", + "duration": 9912000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T11:15:12", + "duration": 9000000, + "percent": 0.4, + "rate": 0.58, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T11:15:12", + "duration": 9000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-23T15:15:12Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T11:15:12", + "duration": 2688000, + "expectedDuration": 9000000, + "percent": 0.4, + "rate": 0.58, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T11:15:12", + "duration": 9000000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-23T15:15:12Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T12:00:00", + "duration": 8340000, + "percent": 0.4, + "rate": 0.26, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T12:00:00", + "duration": 8340000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-23T16:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T12:00:00", + "duration": 5612000, + "expectedDuration": 8340000, + "percent": 0.4, + "rate": 0.26, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T12:00:00", + "duration": 8340000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-23T16:00:00Z", + "timezoneOffset": -240, + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T13:33:32", + "duration": 38000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T10:34:10", + "duration": 627000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T10:44:37", + "duration": 3600000, + "percent": 1.15, + "rate": 1.66, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T10:44:37", + "duration": 3600000, + "rate": 1.44, + "scheduleName": "basal 3", + "time": "2018-10-23T17:44:37Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T11:44:37", + "duration": 923000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T18:00:00", + "duration": 10191000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T20:49:51", + "duration": 12600000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T20:49:51", + "duration": 12600000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-24T03:49:51Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T20:49:51", + "duration": 4209000, + "expectedDuration": 12600000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T20:49:51", + "duration": 12600000, + "rate": 1.15, + "scheduleName": "basal 3", + "time": "2018-10-24T03:49:51Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T22:00:00", + "duration": 12600000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T22:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-24T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T22:00:00", + "duration": 7200000, + "expectedDuration": 12600000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T22:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-24T05:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T00:00:00", + "duration": 12600000, + "percent": 1.4, + "rate": 2.31, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-24T07:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T00:00:00", + "duration": 1191000, + "expectedDuration": 12600000, + "percent": 1.4, + "rate": 2.31, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3", + "time": "2018-10-24T07:00:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T00:19:51", + "duration": 11409000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T03:30:00", + "duration": 2088000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T04:04:48", + "duration": 20248000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T09:42:16", + "duration": 8264000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T12:00:00", + "duration": 7234000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T14:00:34", + "duration": 5400000, + "percent": 1.6, + "rate": 1.04, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T14:00:34", + "duration": 5400000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-10-25T21:00:34Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T15:30:34", + "duration": 8966000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T03:30:00", + "duration": 16729000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:08:49", + "duration": 7200000, + "percent": 1.5, + "rate": 2.32, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:08:49", + "duration": 7200000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-10-27T15:08:49Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:08:49", + "duration": 1271000, + "expectedDuration": 7200000, + "percent": 1.5, + "rate": 2.32, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:08:49", + "duration": 7200000, + "rate": 1.55, + "scheduleName": "basal 3", + "time": "2018-10-27T15:08:49Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:30:00", + "duration": 7200000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-27T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:30:00", + "duration": 5929000, + "expectedDuration": 7200000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3", + "time": "2018-10-27T15:30:00Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T10:08:49", + "duration": 6671000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T12:00:00", + "duration": 65000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T12:01:05", + "duration": 421000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T12:08:06", + "duration": 21114000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T18:00:00", + "duration": 4889000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T19:21:29", + "duration": 14570000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T23:24:19", + "duration": 2141000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T03:30:00", + "duration": 13402000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T07:13:22", + "duration": 17773000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T12:09:35", + "duration": 5452000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T13:40:27", + "duration": 9000000, + "percent": 1.5, + "rate": 0.97, + "suppressed": { + "conversionOffset": 0, + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T13:40:27", + "duration": 9000000, + "rate": 0.65, + "scheduleName": "basal 3", + "time": "2018-11-03T20:40:27Z", + "timezoneOffset": -420, + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T16:10:27", + "duration": 6573000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T03:30:00", + "duration": 6646000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T05:20:46", + "duration": 81000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T04:22:07", + "duration": 14873000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T18:00:00", + "duration": 3581000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "annotations": [{ "code": "basal/unknown-duration" }], + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T18:59:41", + "duration": 0 + } +] +` + +func GetJFBasalData() []map[string]interface{} { + data := []map[string]interface{}{} + json.Unmarshal([]byte(jfBasalStr), &data) + return data +} + +var platformBasalStr = `[ + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T22:00:00", + "duration": 1217000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T22:20:17", + "duration": 800000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-11T22:33:37", + "duration": 5183000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-12T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-13T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-14T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T00:00:00", + "duration": 7992000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T02:13:12", + "duration": 2334000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T05:52:06", + "duration": 6987000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T07:48:33", + "duration": 1140000, + "percent": 0.4, + "rate": 0.62, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T08:07:02", + "duration": 2631000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T08:50:53", + "duration": 8779000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:17:12", + "duration": 1800000, + "percent": 0.6, + "rate": 0.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:47:12", + "duration": 592000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T11:57:04", + "duration": 7200000, + "percent": 0.35, + "rate": 0.5, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.43, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T12:00:00", + "duration": 7200000, + "percent": 0.35, + "rate": 0.22, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.63, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T13:57:04", + "duration": 14576000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-15T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T08:30:00", + "duration": 3356000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T09:25:56", + "duration": 7200000, + "percent": 0.5, + "rate": 0.72, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T11:25:56", + "duration": 2044000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T12:00:00", + "duration": 1425000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T12:23:45", + "duration": 5400000, + "percent": 0.5, + "rate": 0.32, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T13:53:45", + "duration": 14775000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-16T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T00:00:00", + "duration": 2543000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T00:42:23", + "duration": 12600000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T03:30:00", + "duration": 12600000, + "percent": 0.65, + "rate": 0.84, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.29, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T04:12:23", + "duration": 4657000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T08:30:00", + "duration": 10937000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T11:32:17", + "duration": 10800000, + "percent": 0.6, + "rate": 0.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T12:00:00", + "duration": 7860000, + "percent": 0.6, + "rate": 0.39, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T13:42:37", + "duration": 47000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T13:43:24", + "duration": 10800000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T16:43:24", + "duration": 4596000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T18:00:00", + "duration": 2896000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T18:48:16", + "duration": 4862000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T20:09:18", + "duration": 6642000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-17T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-18T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-19T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T00:00:00", + "duration": 10582000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T02:56:22", + "duration": 21600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T03:30:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T05:30:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T08:30:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T08:56:22", + "duration": 11018000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T12:00:00", + "duration": 7848000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T14:10:48", + "duration": 9000000, + "percent": 1.25, + "rate": 0.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T16:40:48", + "duration": 4752000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T18:00:00", + "duration": 4786000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T19:19:46", + "duration": 492000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T19:27:58", + "duration": 9122000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-20T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-21T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T08:30:00", + "duration": 5770000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:06:10", + "duration": 1860000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:36:13", + "duration": 13000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T10:36:26", + "duration": 3600000, + "percent": 1.15, + "rate": 1.66, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T11:36:26", + "duration": 1414000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T12:00:00", + "duration": 19357000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T17:22:37", + "duration": 385000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T17:29:02", + "duration": 1858000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-22T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T12:00:00", + "duration": 499000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T12:08:19", + "duration": 9000000, + "percent": 0.55, + "rate": 0.35, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T14:38:19", + "duration": 8117000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T16:53:36", + "duration": 5400000, + "percent": 1.5, + "rate": 0.97, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T18:00:00", + "duration": 5400000, + "percent": 1.5, + "rate": 1.72, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T18:23:36", + "duration": 12984000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T22:00:00", + "duration": 1335000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-23T22:22:15", + "duration": 7200000, + "percent": 0.7, + "rate": 0.91, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T00:00:00", + "duration": 7200000, + "percent": 0.7, + "rate": 1.01, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T00:22:15", + "duration": 5651000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T01:56:26", + "duration": 16200000, + "percent": 0.5, + "rate": 0.72, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:30:00", + "duration": 6360000, + "percent": 0.5, + "rate": 0.65, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:41:53", + "duration": 14000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:42:07", + "duration": 480000, + "percent": 0.15000000000000002, + "rate": 0.19, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.27, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:49:40", + "duration": 21000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T03:50:01", + "duration": 1260000, + "rate": 0 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T04:10:44", + "duration": 17000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T04:11:01", + "duration": 25200000, + "percent": 0.30000000000000004, + "rate": 0.39, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T05:30:00", + "duration": 25200000, + "percent": 0.30000000000000004, + "rate": 0.46, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.53, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T08:30:00", + "duration": 21000000, + "percent": 0.30000000000000004, + "rate": 0.43, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.43, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T10:00:43", + "duration": 7157000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-24T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T08:30:00", + "duration": 7831000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T10:40:31", + "duration": 3660000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T11:41:01", + "duration": 26048000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T18:55:09", + "duration": 11091000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-25T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T08:30:00", + "duration": 4143000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T09:39:03", + "duration": 5400000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T11:09:03", + "duration": 3057000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-26T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T12:00:00", + "duration": 11173000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T15:06:13", + "duration": 10800000, + "percent": 0.5, + "rate": 0.32, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T18:00:00", + "duration": 10800000, + "percent": 0.5, + "rate": 0.57, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.14, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T18:06:13", + "duration": 14027000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-27T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T05:30:00", + "duration": 7330000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T07:32:10", + "duration": 8320000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T09:50:50", + "duration": 7750000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-28T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-29T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T12:00:00", + "duration": 13768000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T15:49:28", + "duration": 1919000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T13:21:27", + "duration": 16713000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T18:00:00", + "duration": 7752000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T20:09:12", + "duration": 4951000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T21:31:43", + "duration": 1697000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-11-30T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T05:30:00", + "duration": 2075000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T06:04:35", + "duration": 5400000, + "percent": 1.4, + "rate": 2.17, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T07:34:35", + "duration": 3325000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T08:30:00", + "duration": 6166000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T10:12:46", + "duration": 5400000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T11:42:46", + "duration": 1034000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-01T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-02T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T22:00:00", + "duration": 4345000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T23:12:25", + "duration": 1767000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-03T23:41:52", + "duration": 1088000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-04T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-05T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-06T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T05:30:00", + "duration": 7632000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T07:37:12", + "duration": 7359000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T09:39:51", + "duration": 8409000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-07T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-08T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-09T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T08:30:00", + "duration": 7692000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T10:38:12", + "duration": 1864000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T11:09:16", + "duration": 3044000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-10T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-11T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T18:00:00", + "duration": 11017000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T21:03:37", + "duration": 10800000, + "percent": 1.5, + "rate": 1.72, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-12T22:00:00", + "duration": 10800000, + "percent": 1.5, + "rate": 1.95, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T00:00:00", + "duration": 10800000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T00:03:37", + "duration": 12383000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T05:30:00", + "duration": 5676000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T07:04:36", + "duration": 7200000, + "percent": 0.4, + "rate": 0.62, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T08:30:00", + "duration": 7200000, + "percent": 0.4, + "rate": 0.58, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T09:04:36", + "duration": 8062000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T11:18:58", + "duration": 3600000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T12:00:00", + "duration": 3600000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T12:18:58", + "duration": 20462000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T18:00:00", + "duration": 3789000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T19:03:09", + "duration": 4406000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T20:16:35", + "duration": 6205000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-13T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-14T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T12:00:00", + "duration": 21479000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T17:57:59", + "duration": 7200000, + "percent": 1.45, + "rate": 0.94, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T18:00:00", + "duration": 7200000, + "percent": 1.45, + "rate": 1.66, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.14, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T19:57:59", + "duration": 7321000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-15T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T03:30:00", + "duration": 6942000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:25:42", + "duration": 5400000, + "percent": 1.5, + "rate": 1.95, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T05:30:00", + "duration": 5400000, + "percent": 1.5, + "rate": 2.32, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T06:55:42", + "duration": 5658000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T18:00:00", + "duration": 12497000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T21:28:17", + "duration": 2135000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-16T22:03:52", + "duration": 6968000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T00:00:00", + "duration": 4032000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T01:07:12", + "duration": 7200000, + "percent": 1.75, + "rate": 2.53, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T03:07:12", + "duration": 1368000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-17T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T22:00:00", + "duration": 4835000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-18T23:20:35", + "duration": 5400000, + "percent": 1.5, + "rate": 1.95, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T00:00:00", + "duration": 5400000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T00:50:35", + "duration": 9565000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-19T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T05:30:00", + "duration": 1701000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T05:58:21", + "duration": 50296000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T19:56:37", + "duration": 7403000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-20T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-21T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T18:00:00", + "duration": 8649000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T20:24:09", + "duration": 9000000, + "percent": 1.95, + "rate": 2.24, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T22:00:00", + "duration": 9000000, + "percent": 1.95, + "rate": 2.53, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-22T22:54:09", + "duration": 3951000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T18:00:00", + "duration": 366000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T18:06:06", + "duration": 613000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T18:16:19", + "duration": 13421000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-23T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-24T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T03:30:00", + "duration": 5480000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:01:20", + "duration": 12600000, + "percent": 1.6, + "rate": 2.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T05:30:00", + "duration": 12600000, + "percent": 1.6, + "rate": 2.48, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T08:30:00", + "duration": 12600000, + "percent": 1.6, + "rate": 2.32, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T08:31:20", + "duration": 12520000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-25T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T05:30:00", + "duration": 3692000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T06:31:32", + "duration": 14400000, + "percent": 1.65, + "rate": 2.55, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T08:30:00", + "duration": 14400000, + "percent": 1.65, + "rate": 2.39, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T10:31:32", + "duration": 5308000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T18:00:00", + "duration": 9007000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T20:30:07", + "duration": 4826000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T21:50:33", + "duration": 567000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-26T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-27T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-28T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T12:00:00", + "duration": 175000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T12:02:55", + "duration": 203000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T12:06:18", + "duration": 21222000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-29T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T22:00:00", + "duration": 5252000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-30T23:27:32", + "duration": 7200000, + "percent": 1.45, + "rate": 1.88, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T00:00:00", + "duration": 7200000, + "percent": 1.45, + "rate": 2.1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T01:27:32", + "duration": 7348000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2017-12-31T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T05:30:00", + "duration": 10163000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T08:19:23", + "duration": 227000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T08:23:10", + "duration": 410000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-01T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-02T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T08:30:00", + "duration": 1916000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T09:01:56", + "duration": 291000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T09:06:47", + "duration": 10393000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-03T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-04T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T00:00:00", + "duration": 2058000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T00:34:18", + "duration": 18000000, + "percent": 1.3, + "rate": 1.88, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T03:30:00", + "duration": 18000000, + "percent": 1.3, + "rate": 1.69, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T05:30:00", + "duration": 18000000, + "percent": 1.3, + "rate": 2.01, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T05:34:18", + "duration": 10542000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-05T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T00:00:00", + "duration": 5352000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T01:29:12", + "duration": 16200000, + "percent": 1.45, + "rate": 2.1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T03:30:00", + "duration": 16200000, + "percent": 1.45, + "rate": 1.88, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T05:30:00", + "duration": 16200000, + "percent": 1.45, + "rate": 2.24, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T05:59:12", + "duration": 9048000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T08:30:00", + "duration": 10301000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T11:21:41", + "duration": 1674000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T11:49:35", + "duration": 625000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-06T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-07T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-08T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T12:00:00", + "duration": 10354000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T14:52:34", + "duration": 729000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T15:04:43", + "duration": 10517000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-09T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T05:30:00", + "duration": 6107000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T07:11:47", + "duration": 3600000, + "percent": 0.35, + "rate": 0.54, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T08:11:47", + "duration": 1093000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-10T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T08:30:00", + "duration": 5259000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T09:57:39", + "duration": 54000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T09:58:33", + "duration": 7287000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-11T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T22:00:00", + "duration": 4793000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-12T23:19:53", + "duration": 5171000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T00:46:04", + "duration": 9836000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-13T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T12:00:00", + "duration": 19060000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T17:17:40", + "duration": 298000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T17:22:38", + "duration": 2242000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-14T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-15T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-16T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T18:00:00", + "duration": 762000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T18:12:42", + "duration": 364000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T18:18:46", + "duration": 13274000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-17T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-18T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T08:30:00", + "duration": 3806000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T09:33:26", + "duration": 32400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T12:00:00", + "duration": 32400000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T18:00:00", + "duration": 32400000, + "percent": 0.75, + "rate": 0.86, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T18:33:26", + "duration": 12394000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-19T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T08:30:00", + "duration": 12207000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T11:53:27", + "duration": 10800000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T12:00:00", + "duration": 10800000, + "percent": 0.65, + "rate": 0.42, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T14:53:27", + "duration": 11193000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-20T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T00:00:00", + "duration": 4261000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T01:11:01", + "duration": 404000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T01:17:45", + "duration": 7935000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-21T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-22T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-23T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T08:30:00", + "duration": 1757000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T08:59:17", + "duration": 695000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T09:10:52", + "duration": 10148000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-24T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-25T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-26T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T12:00:00", + "duration": 18043000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T17:00:43", + "duration": 2404000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T17:40:47", + "duration": 1153000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-27T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-28T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-29T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-30T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T00:00:00", + "duration": 4572000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T01:16:12", + "duration": 303000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T01:21:15", + "duration": 7725000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T08:30:00", + "duration": 1219000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T08:50:19", + "duration": 5400000, + "percent": 1.3, + "rate": 1.88, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T10:20:19", + "duration": 5981000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-01-31T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-01T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T12:00:00", + "duration": 14758000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T16:05:58", + "duration": 375000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T16:12:13", + "duration": 6467000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T18:00:00", + "duration": 11599000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T21:13:19", + "duration": 711000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T21:25:10", + "duration": 2090000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-02T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T18:00:00", + "duration": 10305000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T20:51:45", + "duration": 7200000, + "percent": 0.19999999999999996, + "rate": 0.23, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T22:00:00", + "duration": 7200000, + "percent": 0.19999999999999996, + "rate": 0.28, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-03T22:51:45", + "duration": 4095000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-04T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T12:00:00", + "duration": 19370000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T17:22:50", + "duration": 3600000, + "percent": 0.7, + "rate": 0.45, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T18:00:00", + "duration": 3600000, + "percent": 0.7, + "rate": 0.8, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.14, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T18:22:50", + "duration": 13030000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-05T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T03:30:00", + "duration": 7580000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T05:36:20", + "duration": 249000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T05:40:29", + "duration": 10171000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-06T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-07T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T08:30:00", + "duration": 169000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T08:32:49", + "duration": 544000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T08:41:53", + "duration": 11887000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-08T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-09T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-10T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T12:00:00", + "duration": 16275000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T16:31:15", + "duration": 455000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T16:38:50", + "duration": 4870000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T18:00:00", + "duration": 13413000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T21:43:33", + "duration": 246000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T21:47:39", + "duration": 741000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-11T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-12T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-13T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-14T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:00:00", + "duration": 643000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:10:43", + "duration": 60000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:10:50", + "duration": 273000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:15:23", + "duration": 28000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T00:15:51", + "duration": 7200000, + "percent": 1.3, + "rate": 1.95, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T02:15:51", + "duration": 4449000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-15T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T00:00:00", + "duration": 10840000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:00:40", + "duration": 10800000, + "percent": 1.45, + "rate": 2.17, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T03:30:00", + "duration": 10800000, + "percent": 1.45, + "rate": 1.95, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.34, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T05:30:00", + "duration": 10800000, + "percent": 1.45, + "rate": 2.24, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T06:00:40", + "duration": 8960000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-16T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-17T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T05:30:00", + "duration": 9662000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T08:11:02", + "duration": 6831000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T10:04:53", + "duration": 973000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T10:21:06", + "duration": 97000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T10:22:43", + "duration": 5837000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T12:00:00", + "duration": 4664000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T13:17:44", + "duration": 7380000, + "percent": 1.5, + "rate": 0.97, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T15:19:49", + "duration": 9611000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-18T22:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-19T22:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-20T22:00:00", + "duration": 7200000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T05:30:00", + "duration": 7957000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T07:42:37", + "duration": 35000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T07:43:12", + "duration": 2808000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T08:30:00", + "duration": 8781000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T10:56:21", + "duration": 254000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T11:00:35", + "duration": 3565000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T00:00:00", + "duration": 4542000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T01:15:42", + "duration": 10800000, + "percent": 0.7, + "rate": 1.05, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T03:30:00", + "duration": 10800000, + "percent": 0.7, + "rate": 0.94, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.34, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T04:15:42", + "duration": 4458000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T18:00:00", + "duration": 366000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T18:06:06", + "duration": 21600000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-22T22:00:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T00:00:00", + "duration": 21600000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T00:06:06", + "duration": 9204000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T02:39:30", + "duration": 18000000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T03:30:00", + "duration": 18000000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.35, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T05:30:00", + "duration": 18000000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T07:39:30", + "duration": 3030000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T08:30:00", + "duration": 8164000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T10:46:04", + "duration": 18000000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T12:00:00", + "duration": 18000000, + "percent": 0.65, + "rate": 0.42, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T15:46:04", + "duration": 8036000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-23T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T12:00:00", + "duration": 21410000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T17:56:50", + "duration": 2163000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T18:32:53", + "duration": 12427000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T22:00:00", + "duration": 5415000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-25T23:30:15", + "duration": 7200000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T00:00:00", + "duration": 7200000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T01:30:15", + "duration": 7185000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T08:30:00", + "duration": 345000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T08:35:45", + "duration": 5400000, + "percent": 0.65, + "rate": 0.94, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T10:05:45", + "duration": 6855000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T18:00:00", + "duration": 9705000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T20:41:45", + "duration": 7200000, + "percent": 1.3, + "rate": 1.49, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T22:00:00", + "duration": 7200000, + "percent": 1.3, + "rate": 1.88, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-27T22:41:45", + "duration": 4695000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T00:00:00", + "duration": 5211000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T01:26:51", + "duration": 199000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T01:30:10", + "duration": 147000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T01:32:37", + "duration": 12600000, + "percent": 0.75, + "rate": 1.12, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.49, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T03:30:00", + "duration": 12600000, + "percent": 0.75, + "rate": 1.01, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.35, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T05:02:37", + "duration": 1643000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-02-28T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-01T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T12:00:00", + "duration": 91000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T12:01:31", + "duration": 7200000, + "percent": 1.35, + "rate": 0.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T14:01:31", + "duration": 14309000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T00:00:00", + "duration": 8771000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T02:26:11", + "duration": 272000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T02:30:43", + "duration": 3557000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-03T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-04T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T08:30:00", + "duration": 5906000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T10:08:26", + "duration": 2274000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T10:46:20", + "duration": 4420000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-06T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-07T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-08T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T18:00:00", + "duration": 2434000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T18:40:34", + "duration": 3332000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T19:36:06", + "duration": 8634000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-09T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-10T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T22:00:00", + "duration": 7042000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T23:57:22", + "duration": 114000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-11T23:59:16", + "duration": 44000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-12T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T08:30:00", + "duration": 135000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T08:32:15", + "duration": 360000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T09:38:15", + "duration": 8505000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-13T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T00:00:00", + "duration": 5721000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T01:35:21", + "duration": 660000, + "percent": 0.6, + "rate": 0.9, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T01:45:59", + "duration": 6241000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T18:00:00", + "duration": 12763000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T21:32:43", + "duration": 200000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T21:36:03", + "duration": 1437000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-15T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T00:00:00", + "duration": 7717000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T02:08:37", + "duration": 9000000, + "percent": 1.2, + "rate": 1.8, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T03:30:00", + "duration": 9000000, + "percent": 1.2, + "rate": 1.62, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.35, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T04:38:37", + "duration": 3083000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-16T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-17T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T00:00:00", + "duration": 1387000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T00:23:07", + "duration": 5575000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T01:56:02", + "duration": 5638000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-18T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-19T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T00:00:00", + "duration": 5074000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T01:24:34", + "duration": 3600000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T02:24:34", + "duration": 3926000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T12:00:00", + "duration": 14636000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T16:03:56", + "duration": 156000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T16:06:32", + "duration": 6808000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-20T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-22T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T12:00:00", + "duration": 261000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T12:04:21", + "duration": 241000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T12:08:22", + "duration": 21098000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-23T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T08:30:00", + "duration": 5750000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T10:05:50", + "duration": 188000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T10:08:58", + "duration": 6662000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-25T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T12:00:00", + "duration": 17191000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T16:46:31", + "duration": 4727000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T18:05:18", + "duration": 14082000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T18:00:00", + "duration": 2581000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T18:43:01", + "duration": 67000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T21:44:08", + "duration": 952000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-28T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T18:00:00", + "duration": 9738000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T20:42:18", + "duration": 1004000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T20:59:02", + "duration": 3658000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-29T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T00:00:00", + "duration": 12403000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:26:43", + "duration": 7200000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T03:30:00", + "duration": 7200000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.35, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T05:26:43", + "duration": 197000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-30T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-03-31T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T18:00:00", + "duration": 3804000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T19:03:24", + "duration": 476000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T19:11:20", + "duration": 10120000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-01T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T08:30:00", + "duration": 3078000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T09:21:18", + "duration": 5400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T10:51:18", + "duration": 4122000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-03T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T18:00:00", + "duration": 8562000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T20:22:42", + "duration": 87000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T17:24:09", + "duration": 2151000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T18:00:00", + "duration": 10423000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T20:53:43", + "duration": 2326000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T21:32:29", + "duration": 1651000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-04T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-06T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T08:30:00", + "duration": 11164000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T11:36:04", + "duration": 7381000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T13:39:05", + "duration": 15655000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-07T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-08T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T18:00:00", + "duration": 6679000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T19:51:19", + "duration": 1653000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T20:18:52", + "duration": 6068000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-09T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T08:30:00", + "duration": 6131000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T10:12:11", + "duration": 1800000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T10:42:11", + "duration": 4669000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-10T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T12:00:00", + "duration": 243000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T12:04:03", + "duration": 36000000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T18:00:00", + "duration": 36000000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T22:00:00", + "duration": 36000000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-11T22:04:02", + "duration": 6958000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T08:30:00", + "duration": 321000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T08:35:21", + "duration": 28800000, + "percent": 0.7, + "rate": 1.01, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T12:00:00", + "duration": 28200000, + "percent": 0.7, + "rate": 0.45, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T16:25:06", + "duration": 17000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T16:25:23", + "duration": 12600000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T18:00:00", + "duration": 12600000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T19:55:23", + "duration": 7477000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T22:00:00", + "duration": 5512000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T23:31:52", + "duration": 351000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T23:37:43", + "duration": 562000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-12T23:47:05", + "duration": 36000000, + "percent": 0.6, + "rate": 0.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:00:00", + "duration": 840000, + "percent": 0.6, + "rate": 0.9, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:01:02", + "duration": 13000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T00:01:15", + "duration": 10380000, + "percent": 0.5, + "rate": 0.75, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T02:54:02", + "duration": 17000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T02:54:19", + "duration": 27000000, + "percent": 0.35, + "rate": 0.52, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.49, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T03:30:00", + "duration": 27000000, + "percent": 0.35, + "rate": 0.47, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.34, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T05:30:00", + "duration": 14700000, + "percent": 0.35, + "rate": 0.54, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T06:59:14", + "duration": 5446000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T08:30:00", + "duration": 1684000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T08:58:04", + "duration": 3600000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T09:58:04", + "duration": 211000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T10:01:35", + "duration": 3600000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T11:01:35", + "duration": 3505000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T12:00:00", + "duration": 1514000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T12:25:14", + "duration": 12840000, + "percent": 0.55, + "rate": 0.35, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T15:58:44", + "duration": 8000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T15:58:52", + "duration": 5400000, + "percent": 1.25, + "rate": 0.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T17:28:52", + "duration": 1868000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T18:00:00", + "duration": 4291000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T19:11:31", + "duration": 60000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T19:12:19", + "duration": 10061000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-13T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T00:00:00", + "duration": 2499000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T00:41:39", + "duration": 7200000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T02:41:39", + "duration": 2901000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T05:30:00", + "duration": 10759000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T08:29:19", + "duration": 4125000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T09:38:04", + "duration": 8516000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T12:00:00", + "duration": 4493000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T13:14:53", + "duration": 3600000, + "percent": 0.9, + "rate": 0.58, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T14:14:53", + "duration": 13507000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-15T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-16T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T05:30:00", + "duration": 8560000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T07:52:40", + "duration": 8961000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T10:22:01", + "duration": 5879000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T22:00:00", + "duration": 6208000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-17T23:43:28", + "duration": 7200000, + "percent": 1.1, + "rate": 1.59, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T00:00:00", + "duration": 7200000, + "percent": 1.1, + "rate": 1.65, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T01:43:28", + "duration": 6392000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T12:00:00", + "duration": 11187000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T15:06:27", + "duration": 3600000, + "percent": 0.7, + "rate": 0.45, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T16:06:27", + "duration": 6813000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-18T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-19T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T08:30:00", + "duration": 7374000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T10:32:54", + "duration": 790000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T10:46:04", + "duration": 4436000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-20T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T05:30:00", + "duration": 10425000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T08:23:45", + "duration": 375000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T12:00:00", + "duration": 10788000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T14:59:48", + "duration": 3678000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T16:01:06", + "duration": 7134000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T12:00:00", + "duration": 9679000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T14:41:19", + "duration": 10800000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T17:41:19", + "duration": 1121000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-22T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T22:00:00", + "duration": 4227000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T23:10:27", + "duration": 586000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-23T23:20:13", + "duration": 2387000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T18:00:00", + "duration": 13412000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T21:43:32", + "duration": 200000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T21:46:52", + "duration": 788000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-25T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T00:00:00", + "duration": 3746000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:02:26", + "duration": 180000, + "percent": 0.7, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:04:34", + "duration": 11000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T01:04:45", + "duration": 18000000, + "percent": 0.85, + "rate": 1.31, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T03:30:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.19, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T05:30:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.36, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T06:04:45", + "duration": 8715000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T00:00:00", + "duration": 10498000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T02:54:58", + "duration": 21600000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T03:30:00", + "duration": 21600000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T05:30:00", + "duration": 21600000, + "percent": 0.75, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T08:30:00", + "duration": 21600000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T08:54:58", + "duration": 11102000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T22:00:00", + "duration": 4513000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T23:15:13", + "duration": 147000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-28T23:17:40", + "duration": 2540000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-29T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-04-30T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-01T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T00:00:00", + "duration": 635000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T00:10:35", + "duration": 315000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T00:15:50", + "duration": 11650000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T18:00:00", + "duration": 1631000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T18:27:11", + "duration": 3420000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T19:24:10", + "duration": 9350000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T05:30:00", + "duration": 3903000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T06:35:03", + "duration": 7200000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T08:30:00", + "duration": 7200000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T08:35:03", + "duration": 2092000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T09:09:55", + "duration": 43200000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T12:00:00", + "duration": 16200000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T13:39:54", + "duration": 221000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T13:43:35", + "duration": 10550000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T16:39:25", + "duration": 21498000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-03T22:37:43", + "duration": 4937000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T00:00:00", + "duration": 5097000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T01:24:57", + "duration": 30600000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T03:30:00", + "duration": 30600000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.35, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T05:30:00", + "duration": 30600000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T08:30:00", + "duration": 30600000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T09:54:57", + "duration": 4178000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T11:04:35", + "duration": 41400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T12:00:00", + "duration": 41400000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T18:00:00", + "duration": 41400000, + "percent": 0.75, + "rate": 0.86, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T22:00:00", + "duration": 41400000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-04T22:34:35", + "duration": 5125000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T00:00:00", + "duration": 4232000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T01:10:32", + "duration": 28800000, + "percent": 0.75, + "rate": 1.12, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.49, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T03:30:00", + "duration": 28800000, + "percent": 0.75, + "rate": 1.01, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.35, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T05:30:00", + "duration": 28800000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T08:30:00", + "duration": 28800000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T09:10:32", + "duration": 10168000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T05:30:00", + "duration": 10250000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:20:50", + "duration": 28800000, + "percent": 0.75, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T08:30:00", + "duration": 28800000, + "percent": 0.75, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T12:00:00", + "duration": 28800000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T16:20:50", + "duration": 5950000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T18:00:00", + "duration": 9910000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T20:45:10", + "duration": 257000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T20:49:27", + "duration": 4233000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-06T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-07T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-08T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-09T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T03:30:00", + "duration": 4311000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T04:41:51", + "duration": 18428000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T09:48:59", + "duration": 7861000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T18:00:00", + "duration": 11857000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T21:17:37", + "duration": 10800000, + "percent": 1.15, + "rate": 1.32, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T22:00:00", + "duration": 5460000, + "percent": 1.15, + "rate": 1.66, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T22:48:11", + "duration": 2421000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-10T23:28:32", + "duration": 3600000, + "percent": 1.25, + "rate": 1.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T00:00:00", + "duration": 3600000, + "percent": 1.25, + "rate": 1.93, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T00:28:32", + "duration": 10888000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-11T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T05:30:00", + "duration": 10800000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T12:00:00", + "duration": 21052000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T17:50:52", + "duration": 10800000, + "percent": 1.25, + "rate": 0.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T18:00:00", + "duration": 10800000, + "percent": 1.25, + "rate": 1.43, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.14, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T20:50:52", + "duration": 4148000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-12T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T03:30:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T05:30:00", + "duration": 1821000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T06:00:21", + "duration": 217000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T06:03:58", + "duration": 8762000, + "rate": 1.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-13T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T18:00:00", + "duration": 2689000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T18:44:49", + "duration": 3986000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T19:51:15", + "duration": 7725000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T18:00:00", + "duration": 8609000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T20:23:29", + "duration": 9000000, + "percent": 1.5, + "rate": 1.72, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T22:00:00", + "duration": 7140000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-15T22:21:32", + "duration": 5908000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-16T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T12:00:00", + "duration": 16133000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T16:28:53", + "duration": 113000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T16:30:46", + "duration": 5354000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-17T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-18T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-19T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T12:00:00", + "duration": 19563000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T17:26:03", + "duration": 368000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T17:32:11", + "duration": 1669000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-20T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T22:00:00", + "duration": 1859000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T22:30:59", + "duration": 3600000, + "percent": 1.95, + "rate": 2.82, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-22T23:30:59", + "duration": 1741000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T08:30:00", + "duration": 8897000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T10:58:17", + "duration": 1755000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T11:27:32", + "duration": 1948000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T12:00:00", + "duration": 19655000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T17:27:35", + "duration": 375000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T17:33:50", + "duration": 1570000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T18:00:00", + "duration": 13374000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T21:42:54", + "duration": 10800000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-23T22:00:00", + "duration": 10800000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T00:00:00", + "duration": 10800000, + "percent": 1.4, + "rate": 2.1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T00:42:54", + "duration": 10026000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-25T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T08:30:00", + "duration": 11426000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T11:40:26", + "duration": 7949000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T13:52:55", + "duration": 14825000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-28T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T08:30:00", + "duration": 2522000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T09:12:02", + "duration": 14514000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T13:13:56", + "duration": 17164000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T18:00:00", + "duration": 14339000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T21:58:59", + "duration": 1800000, + "percent": 0.09999999999999998, + "rate": 0.11, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.1, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T22:00:00", + "duration": 1800000, + "percent": 0.09999999999999998, + "rate": 0.14, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-29T22:28:59", + "duration": 5461000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T12:00:00", + "duration": 20380000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T17:39:40", + "duration": 3600000, + "percent": 0.65, + "rate": 0.42, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T18:00:00", + "duration": 3600000, + "percent": 0.65, + "rate": 0.74, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.14, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T18:39:40", + "duration": 12020000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T22:00:00", + "duration": 1941000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T22:32:21", + "duration": 332000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-30T22:37:53", + "duration": 4927000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-05-31T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T00:00:00", + "duration": 7844000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T02:10:44", + "duration": 5400000, + "percent": 0.6, + "rate": 0.9, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T03:30:00", + "duration": 5400000, + "percent": 0.6, + "rate": 0.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.35, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T03:40:44", + "duration": 6556000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T22:00:00", + "duration": 89000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T22:01:29", + "duration": 427000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-01T22:08:36", + "duration": 6684000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T12:00:00", + "duration": 6521000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:48:41", + "duration": 180000, + "percent": 0.6, + "rate": 0.39, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:51:15", + "duration": 329000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T13:56:44", + "duration": 5400000, + "percent": 1.2, + "rate": 0.78, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T15:26:44", + "duration": 9196000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-03T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-04T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T00:00:00", + "duration": 2718000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T00:45:18", + "duration": 410000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T00:52:08", + "duration": 9472000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T18:00:00", + "duration": 9098000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T20:31:38", + "duration": 238000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T20:35:36", + "duration": 5064000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T12:00:00", + "duration": 6090000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T13:41:30", + "duration": 277000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T13:46:07", + "duration": 8525000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-07T15:08:12", + "duration": 13000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-06T16:08:25", + "duration": 10295000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-07T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-07T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T12:00:00", + "duration": 537000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T12:08:57", + "duration": 190000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T12:12:07", + "duration": 20873000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T12:00:00", + "duration": 3798000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T13:03:18", + "duration": 482000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T14:12:18", + "duration": 13662000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-08T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T03:30:00", + "duration": 3971000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T04:36:11", + "duration": 250000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T04:40:21", + "duration": 2979000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-09T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T22:00:00", + "duration": 3091000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T22:51:31", + "duration": 1929000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-10T23:23:40", + "duration": 2180000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-11T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T12:00:00", + "duration": 2125000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T12:35:25", + "duration": 1737000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T13:04:22", + "duration": 17738000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-12T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-13T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T00:00:00", + "duration": 1723000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T00:28:43", + "duration": 27000000, + "percent": 0.65, + "rate": 0.97, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.49, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T03:30:00", + "duration": 27000000, + "percent": 0.65, + "rate": 0.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.34, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T05:30:00", + "duration": 27000000, + "percent": 0.65, + "rate": 1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T07:58:43", + "duration": 1877000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T12:00:00", + "duration": 11186000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T15:06:26", + "duration": 10709000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T18:04:55", + "duration": 14105000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-15T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-16T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-17T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T08:30:00", + "duration": 7555000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T10:35:55", + "duration": 27000000, + "percent": 0.8, + "rate": 1.16, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T12:00:00", + "duration": 27000000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T18:00:00", + "duration": 27000000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T18:05:54", + "duration": 6111000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T19:47:45", + "duration": 18000000, + "percent": 0.85, + "rate": 0.97, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.14, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-18T22:00:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.23, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T00:00:00", + "duration": 17880000, + "percent": 0.85, + "rate": 1.27, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.49, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T00:44:56", + "duration": 112000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T00:46:48", + "duration": 9792000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T18:00:00", + "duration": 10769000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T20:59:29", + "duration": 3631000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-19T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-20T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T08:30:00", + "duration": 10621000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T11:27:01", + "duration": 25200000, + "percent": 0.8, + "rate": 1.12, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T12:00:00", + "duration": 14160000, + "percent": 0.8, + "rate": 0.48, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T15:22:15", + "duration": 52000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T18:23:07", + "duration": 13013000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T22:00:00", + "duration": 6238000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T23:43:58", + "duration": 870000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-21T23:58:28", + "duration": 92000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-22T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-23T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T00:00:00", + "duration": 9249000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T02:34:09", + "duration": 9000000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T03:30:00", + "duration": 9000000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.35, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T05:04:09", + "duration": 1551000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T08:30:00", + "duration": 6845000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T10:24:05", + "duration": 10800000, + "percent": 1.35, + "rate": 1.89, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T12:00:00", + "duration": 10800000, + "percent": 1.35, + "rate": 0.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T13:24:05", + "duration": 16555000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-24T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T05:30:00", + "duration": 8167000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T07:46:07", + "duration": 5319000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T09:14:46", + "duration": 9914000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T22:00:00", + "duration": 2939000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T22:48:59", + "duration": 3600000, + "percent": 0.85, + "rate": 1.19, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-25T23:48:59", + "duration": 661000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T00:00:00", + "duration": 10930000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T03:02:10", + "duration": 56000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T00:03:06", + "duration": 12414000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-26T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T12:00:00", + "duration": 16156000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T16:29:16", + "duration": 5400000, + "percent": 1.4, + "rate": 0.84, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T17:59:16", + "duration": 44000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-27T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T12:00:00", + "duration": 7901000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T14:11:41", + "duration": 1866000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T14:42:47", + "duration": 11833000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-28T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T08:30:00", + "duration": 7554000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T10:35:54", + "duration": 27000000, + "percent": 0.85, + "rate": 1.19, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T12:00:00", + "duration": 27000000, + "percent": 0.85, + "rate": 0.51, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T18:00:00", + "duration": 27000000, + "percent": 0.85, + "rate": 0.89, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T18:05:54", + "duration": 14046000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T22:00:00", + "duration": 5283000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-06-29T23:28:03", + "duration": 3855000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T00:32:18", + "duration": 10662000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T18:00:00", + "duration": 6951000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T19:55:51", + "duration": 7449000, + "rate": 1, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-06-30T22:00:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T00:00:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T03:30:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T05:30:00", + "duration": 10800000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T08:30:00", + "duration": 10564000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T11:26:04", + "duration": 139000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T11:28:23", + "duration": 1897000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-01T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T00:00:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T03:30:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-02T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T00:00:00", + "duration": 11060000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:04:20", + "duration": 21600000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T03:30:00", + "duration": 21600000, + "percent": 0.75, + "rate": 0.93, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.24, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T05:30:00", + "duration": 19560000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T08:27:11", + "duration": 10538000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T11:22:49", + "duration": 2231000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-03T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T00:00:00", + "duration": 10459000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T02:54:19", + "duration": 7200000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T03:30:00", + "duration": 7200000, + "percent": 0.75, + "rate": 0.93, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.24, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T04:54:19", + "duration": 2141000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-04T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T00:00:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T03:30:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-05T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T00:00:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T03:30:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T18:00:00", + "duration": 4501000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T19:15:01", + "duration": 442000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T19:22:23", + "duration": 9457000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-06T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T00:00:00", + "duration": 9207000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T02:33:27", + "duration": 3600000, + "percent": 1.35, + "rate": 1.89, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T03:30:00", + "duration": 3600000, + "percent": 1.35, + "rate": 1.68, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.24, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T03:33:27", + "duration": 6993000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T05:30:00", + "duration": 10800000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T08:30:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T18:00:00", + "duration": 14400000, + "rate": 0.95, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-07T22:00:00", + "duration": 7200000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T00:00:00", + "duration": 7931000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T02:12:11", + "duration": 1802000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T02:42:13", + "duration": 2867000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-08T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-09T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T00:00:00", + "duration": 1644000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T00:27:24", + "duration": 387000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T00:33:51", + "duration": 10569000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-10T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-11T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-12T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T05:30:00", + "duration": 11850000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T08:47:30", + "duration": 7734000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T10:56:24", + "duration": 3816000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-13T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T12:00:00", + "duration": 11503000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T15:11:43", + "duration": 238000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T15:15:41", + "duration": 9859000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-14T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T00:00:00", + "duration": 11695000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:14:55", + "duration": 18000000, + "percent": 0.85, + "rate": 1.1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.29, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T03:30:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.02, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.2, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T05:30:00", + "duration": 18000000, + "percent": 0.85, + "rate": 1.1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.29, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T08:14:55", + "duration": 905000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-15T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T08:30:00", + "duration": 4149000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T09:39:09", + "duration": 6405000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T11:25:54", + "duration": 2046000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-16T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T12:00:00", + "duration": 10914000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T15:01:54", + "duration": 3600000, + "percent": 1.25, + "rate": 0.56, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T16:01:54", + "duration": 7086000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-17T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-18T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T12:00:00", + "duration": 14774000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T16:06:14", + "duration": 789000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T16:19:23", + "duration": 6037000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T18:00:00", + "duration": 5447000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T19:30:47", + "duration": 10800000, + "percent": 1.15, + "rate": 1.03, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.9, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T22:00:00", + "duration": 10800000, + "percent": 1.15, + "rate": 1.43, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.24, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-19T22:30:47", + "duration": 5353000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-20T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-21T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T00:00:00", + "duration": 7351000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T02:02:31", + "duration": 5400000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T03:30:00", + "duration": 5400000, + "percent": 0.8, + "rate": 0.96, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.2, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T03:32:31", + "duration": 7049000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-22T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T00:00:00", + "duration": 829000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T00:13:49", + "duration": 2232000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T00:51:01", + "duration": 9539000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-23T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-24T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-25T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T08:30:00", + "duration": 1596000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T08:56:36", + "duration": 882000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T09:11:18", + "duration": 10122000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T18:00:00", + "duration": 124000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T18:02:04", + "duration": 5400000, + "percent": 0.85, + "rate": 0.76, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.89, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T19:32:04", + "duration": 8876000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-26T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-27T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-28T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T00:00:00", + "duration": 860000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T00:14:20", + "duration": 2644000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T00:58:24", + "duration": 9096000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-29T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T18:00:00", + "duration": 1335000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T18:22:15", + "duration": 5400000, + "percent": 0.4, + "rate": 0.36, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.9, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T19:52:15", + "duration": 7665000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-30T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-07-31T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T00:00:00", + "duration": 7906000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T02:11:46", + "duration": 21445000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T08:09:11", + "duration": 1249000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-01T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-02T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T00:00:00", + "duration": 6044000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T01:40:44", + "duration": 5880000, + "percent": 0.85, + "rate": 1.1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.29, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:18:31", + "duration": 9000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:18:40", + "duration": 7200000, + "percent": 0.7, + "rate": 0.91, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T03:30:00", + "duration": 7200000, + "percent": 0.7, + "rate": 0.84, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.2, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T05:18:40", + "duration": 680000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T12:00:00", + "duration": 8453000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T14:20:53", + "duration": 326000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T14:26:19", + "duration": 12821000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-03T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-04T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T12:00:00", + "duration": 18803000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T17:13:23", + "duration": 7200000, + "percent": 1.25, + "rate": 0.56, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T18:00:00", + "duration": 7200000, + "percent": 1.25, + "rate": 1.12, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.9, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T19:13:23", + "duration": 9106000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T21:45:09", + "duration": 251000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T21:49:20", + "duration": 640000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-05T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-06T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-07T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T05:30:00", + "duration": 9183000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T08:03:03", + "duration": 1617000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-08T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T03:30:00", + "duration": 5472000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T05:01:12", + "duration": 180000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T05:04:12", + "duration": 1548000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-09T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-10T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T18:00:00", + "duration": 13178000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T21:39:38", + "duration": 3600000, + "percent": 1.15, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.04, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T22:00:00", + "duration": 3600000, + "percent": 1.15, + "rate": 1.61, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-11T22:39:38", + "duration": 4822000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T12:00:00", + "duration": 4236000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T13:10:36", + "duration": 3620000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T14:10:56", + "duration": 3631000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T15:11:27", + "duration": 600000, + "percent": 0.8, + "rate": 0.48, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T15:21:15", + "duration": 7934000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T17:33:29", + "duration": 1591000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-12T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-13T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T00:00:00", + "duration": 8499000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T02:21:39", + "duration": 16200000, + "percent": 0.8, + "rate": 1.2, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T03:30:00", + "duration": 16200000, + "percent": 0.8, + "rate": 1.08, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.35, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T05:30:00", + "duration": 16200000, + "percent": 0.8, + "rate": 1.24, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T06:51:39", + "duration": 5901000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T18:00:00", + "duration": 3812000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T19:03:32", + "duration": 6060000, + "percent": 0.75, + "rate": 0.78, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.04, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T20:44:03", + "duration": 9000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T20:44:12", + "duration": 5400000, + "percent": 0.65, + "rate": 0.68, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T22:00:00", + "duration": 5400000, + "percent": 0.65, + "rate": 0.91, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-14T22:14:12", + "duration": 6348000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T08:30:00", + "duration": 7596000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T10:36:36", + "duration": 5004000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T18:00:00", + "duration": 57000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T18:00:57", + "duration": 10800000, + "percent": 0.19999999999999996, + "rate": 0.18, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.9, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T21:00:57", + "duration": 2953000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T21:50:10", + "duration": 240000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T21:54:10", + "duration": 350000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-15T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-16T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-17T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-18T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T05:30:00", + "duration": 1539000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T05:55:39", + "duration": 255000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T05:59:54", + "duration": 9006000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-19T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T12:00:00", + "duration": 19916000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T17:31:56", + "duration": 9000000, + "percent": 0.6, + "rate": 0.27, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T18:00:00", + "duration": 9000000, + "percent": 0.6, + "rate": 0.54, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.9, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T20:01:56", + "duration": 7084000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-20T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T12:00:00", + "duration": 12721000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T15:32:01", + "duration": 1800000, + "percent": 0.7, + "rate": 0.31, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T16:02:01", + "duration": 7079000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-21T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T12:00:00", + "duration": 6854000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T13:54:14", + "duration": 473000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T14:02:07", + "duration": 14273000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-22T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T00:00:00", + "duration": 11831000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:17:11", + "duration": 25200000, + "percent": 0.75, + "rate": 0.97, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.29, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T03:30:00", + "duration": 25200000, + "percent": 0.75, + "rate": 0.9, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.2, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T05:30:00", + "duration": 25200000, + "percent": 0.75, + "rate": 0.97, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.29, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T08:30:00", + "duration": 25200000, + "percent": 0.75, + "rate": 0.93, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.24, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T10:17:11", + "duration": 6169000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-23T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T00:00:00", + "duration": 7034000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T01:57:14", + "duration": 25200000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T03:30:00", + "duration": 25200000, + "percent": 0.8, + "rate": 0.96, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.2, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T05:30:00", + "duration": 25200000, + "percent": 0.8, + "rate": 1.04, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.3, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T08:30:00", + "duration": 25200000, + "percent": 0.8, + "rate": 1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.25, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T08:57:14", + "duration": 10966000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T12:00:00", + "duration": 8532000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T14:22:12", + "duration": 7200000, + "percent": 0.30000000000000004, + "rate": 0.13, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.43, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T16:22:12", + "duration": 5868000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-24T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T18:00:00", + "duration": 14095000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T21:54:55", + "duration": 280000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T21:59:35", + "duration": 25000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-25T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-26T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-27T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-28T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T03:30:00", + "duration": 6075000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T05:11:15", + "duration": 397000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T05:17:52", + "duration": 728000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-29T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-30T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T12:00:00", + "duration": 21600000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T18:00:00", + "duration": 14400000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-08-31T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T08:30:00", + "duration": 12600000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T12:00:00", + "duration": 4392000, + "rate": 0.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T13:13:12", + "duration": 17592000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T18:06:24", + "duration": 14016000, + "rate": 0.9, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-01T22:00:00", + "duration": 7200000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T00:00:00", + "duration": 12600000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T03:30:00", + "duration": 7200000, + "rate": 1.2, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T05:30:00", + "duration": 10800000, + "rate": 1.3, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T08:30:00", + "duration": 9169000, + "rate": 1.25, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T11:02:49", + "duration": 3431000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-02T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-03T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T05:30:00", + "duration": 4177000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T06:39:37", + "duration": 10025000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T09:26:42", + "duration": 9198000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-04T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-05T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-06T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T12:00:00", + "duration": 19217000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T17:20:17", + "duration": 6688000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T19:11:45", + "duration": 10095000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-07T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-08T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-09T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-10T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T00:00:00", + "duration": 1827000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T00:30:27", + "duration": 1374000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T00:53:21", + "duration": 9399000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-11T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-12T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-13T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T08:30:00", + "duration": 2264000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T09:07:44", + "duration": 7415000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T11:11:19", + "duration": 1593000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T11:37:52", + "duration": 5400000, + "percent": 1.35, + "rate": 1.89, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T12:00:00", + "duration": 5400000, + "percent": 1.35, + "rate": 0.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T13:07:52", + "duration": 17528000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-14T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T12:00:00", + "duration": 142000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T12:02:22", + "duration": 3600000, + "percent": 0.7, + "rate": 0.42, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T13:02:22", + "duration": 17858000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-15T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T08:30:00", + "duration": 5863000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T10:07:43", + "duration": 5400000, + "percent": 0.75, + "rate": 1.05, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T11:37:43", + "duration": 1337000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-16T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T18:00:00", + "duration": 4181000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T19:09:41", + "duration": 3495000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T20:07:56", + "duration": 6724000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-17T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-18T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T12:00:00", + "duration": 5103000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T13:25:03", + "duration": 76000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T13:26:19", + "duration": 16421000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T18:00:00", + "duration": 13638000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T21:47:18", + "duration": 533000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T21:56:11", + "duration": 229000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-19T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T18:00:00", + "duration": 2999000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T18:49:59", + "duration": 3600000, + "percent": 1.45, + "rate": 1.52, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T19:49:59", + "duration": 7801000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-20T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T00:00:00", + "duration": 2319000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T00:38:39", + "duration": 7200000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T02:38:39", + "duration": 3081000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-21T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T00:00:00", + "duration": 1518000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T00:25:18", + "duration": 3600000, + "percent": 0.7, + "rate": 1.05, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T01:25:18", + "duration": 7482000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-22T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T05:30:00", + "duration": 1230000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T05:50:30", + "duration": 18830000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T11:04:20", + "duration": 3340000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T12:00:00", + "duration": 19246000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T17:20:46", + "duration": 7200000, + "percent": 1.7, + "rate": 1.02, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T18:00:00", + "duration": 7200000, + "percent": 1.7, + "rate": 1.78, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T19:20:46", + "duration": 9554000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-23T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T08:30:00", + "duration": 2085000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T09:04:45", + "duration": 4217000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T10:15:02", + "duration": 6298000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-24T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-25T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T12:00:00", + "duration": 17944000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T16:59:04", + "duration": 3600000, + "percent": 1.65, + "rate": 0.99, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T17:59:04", + "duration": 56000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T18:00:00", + "duration": 5666000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T19:34:26", + "duration": 5400000, + "percent": 1.9, + "rate": 1.99, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T21:04:26", + "duration": 3334000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-26T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T00:00:00", + "duration": 2082000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T00:34:42", + "duration": 3600000, + "percent": 1.35, + "rate": 2.02, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T01:34:42", + "duration": 6918000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T12:00:00", + "duration": 5752000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T13:35:52", + "duration": 204000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T13:39:16", + "duration": 5345000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T15:08:21", + "duration": 5400000, + "percent": 1.55, + "rate": 0.93, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T16:38:21", + "duration": 4899000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T18:00:00", + "duration": 6720000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T19:52:00", + "duration": 645000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T20:02:45", + "duration": 7035000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-27T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T05:30:00", + "duration": 9805000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:13:25", + "duration": 5400000, + "percent": 1.5, + "rate": 2.32, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T08:30:00", + "duration": 5400000, + "percent": 1.5, + "rate": 2.1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T09:43:25", + "duration": 8195000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T12:00:00", + "duration": 2532000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T12:42:12", + "duration": 4620000, + "percent": 1.4, + "rate": 0.84, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T13:58:48", + "duration": 14000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T13:59:02", + "duration": 5400000, + "percent": 1.55, + "rate": 0.93, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T15:29:02", + "duration": 6819000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T17:22:41", + "duration": 7200000, + "percent": 1.35, + "rate": 0.81, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T18:00:00", + "duration": 7200000, + "percent": 1.35, + "rate": 1.41, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.04, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T19:22:41", + "duration": 9439000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-28T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T00:00:00", + "duration": 9113000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T02:31:53", + "duration": 5400000, + "percent": 1.25, + "rate": 1.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T03:30:00", + "duration": 5400000, + "percent": 1.25, + "rate": 1.68, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.34, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T04:01:53", + "duration": 5287000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T08:30:00", + "duration": 4914000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T09:51:54", + "duration": 9000000, + "percent": 0.8, + "rate": 1.12, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T12:00:00", + "duration": 9000000, + "percent": 0.8, + "rate": 0.48, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T12:21:54", + "duration": 20286000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T18:00:00", + "duration": 1416000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T18:23:36", + "duration": 10800000, + "percent": 1.5, + "rate": 1.57, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T21:23:36", + "duration": 2184000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-29T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T08:30:00", + "duration": 3040000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T09:20:40", + "duration": 3159000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T10:13:19", + "duration": 6401000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T12:00:00", + "duration": 4788000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T13:19:48", + "duration": 7200000, + "percent": 1.45, + "rate": 0.87, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T15:19:48", + "duration": 4339000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T16:32:07", + "duration": 7200000, + "percent": 1.5, + "rate": 0.9, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T18:00:00", + "duration": 7200000, + "percent": 1.5, + "rate": 1.57, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T18:32:07", + "duration": 12473000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-09-30T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T18:00:00", + "duration": 4755000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T19:19:15", + "duration": 9000000, + "percent": 1.5, + "rate": 1.57, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T21:49:15", + "duration": 645000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-01T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T18:00:00", + "duration": 12431000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T21:27:11", + "duration": 10800000, + "percent": 1.95, + "rate": 2.04, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-02T22:00:00", + "duration": 10800000, + "percent": 1.95, + "rate": 2.73, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T00:00:00", + "duration": 10800000, + "percent": 1.95, + "rate": 2.92, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.5, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T00:27:11", + "duration": 10969000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T18:00:00", + "duration": 260000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T18:04:20", + "duration": 3314000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T18:59:34", + "duration": 7000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T18:59:41", + "duration": 45000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T19:00:26", + "duration": 10774000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-03T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T00:00:00", + "duration": 12600000, + "rate": 1.5, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T03:30:00", + "duration": 7200000, + "rate": 1.35, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T05:30:00", + "duration": 7859000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T07:40:59", + "duration": 36000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T07:41:35", + "duration": 2905000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T08:30:00", + "duration": 5764000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T10:06:04", + "duration": 7200000, + "percent": 1.25, + "rate": 1.75, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T12:00:00", + "duration": 7200000, + "percent": 1.25, + "rate": 0.75, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T12:06:04", + "duration": 21236000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-04T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T08:30:00", + "duration": 11084000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T11:34:44", + "duration": 3600000, + "percent": 0.7, + "rate": 0.98, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T12:00:00", + "duration": 3600000, + "percent": 0.7, + "rate": 0.42, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.6, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T12:34:44", + "duration": 19516000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-05T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T12:00:00", + "duration": 12872000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T15:34:32", + "duration": 4983000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T16:57:35", + "duration": 3745000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T18:00:00", + "duration": 5583000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T19:33:03", + "duration": 7200000, + "percent": 1.55, + "rate": 1.62, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.05, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T21:33:03", + "duration": 1617000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-06T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T00:00:00", + "duration": 2776000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T00:46:16", + "duration": 7200000, + "percent": 1.3, + "rate": 2.01, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T02:46:16", + "duration": 2624000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T22:00:00", + "duration": 1978000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-07T22:32:58", + "duration": 14400000, + "percent": 1.75, + "rate": 2.45, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T00:00:00", + "duration": 14400000, + "percent": 1.75, + "rate": 2.71, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T02:32:58", + "duration": 3422000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T05:30:00", + "duration": 10800000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T08:30:00", + "duration": 12600000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T18:00:00", + "duration": 14400000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-08T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T00:00:00", + "duration": 12600000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T03:30:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T05:30:00", + "duration": 8216000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T07:46:56", + "duration": 670000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T07:58:06", + "duration": 9000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T07:58:15", + "duration": 3600000, + "percent": 1.45, + "rate": 2.24, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T08:30:00", + "duration": 3600000, + "percent": 1.45, + "rate": 2.03, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.4, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T08:58:15", + "duration": 10905000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T12:00:00", + "duration": 21600000, + "rate": 0.6, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T18:00:00", + "duration": 1977000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T18:32:57", + "duration": 4784000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T19:52:41", + "duration": 7639000, + "rate": 1.05, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-09T22:00:00", + "duration": 7200000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T08:30:00", + "duration": 993000, + "rate": 1.4, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T08:46:33", + "duration": 11607000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-10T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-11T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T03:30:00", + "duration": 14251000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T07:27:31", + "duration": 3604000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T08:27:35", + "duration": 145000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T12:00:00", + "duration": 1528000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T12:25:28", + "duration": 5400000, + "percent": 0.75, + "rate": 0.48, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.64, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T13:55:27", + "duration": 14673000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-12T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:00:00", + "duration": 887000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:14:47", + "duration": 60000, + "percent": 0.6, + "rate": 0.99, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:15:04", + "duration": 23000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T00:15:27", + "duration": 3147000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T01:07:54", + "duration": 435000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T04:15:09", + "duration": 14000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T04:15:23", + "duration": 9240000, + "percent": 0.65, + "rate": 1, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T06:46:52", + "duration": 297000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T06:51:49", + "duration": 17000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T06:52:06", + "duration": 3600000, + "percent": 0.85, + "rate": 1.31, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.54, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T07:52:06", + "duration": 2274000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T18:00:00", + "duration": 10401000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T20:53:21", + "duration": 16200000, + "percent": 1.65, + "rate": 1.89, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-13T22:00:00", + "duration": 16200000, + "percent": 1.65, + "rate": 2.39, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T00:00:00", + "duration": 16200000, + "percent": 1.65, + "rate": 2.72, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T01:23:21", + "duration": 566000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T01:32:47", + "duration": 12600000, + "percent": 1.65, + "rate": 2.72, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T03:30:00", + "duration": 12600000, + "percent": 1.65, + "rate": 2.55, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T05:02:47", + "duration": 12433000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T12:00:00", + "duration": 18910000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T17:15:10", + "duration": 10800000, + "percent": 1.45, + "rate": 0.94, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T18:00:00", + "duration": 10800000, + "percent": 1.45, + "rate": 1.66, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.14, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T20:15:10", + "duration": 6290000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-14T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T12:00:00", + "duration": 8739000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T14:25:39", + "duration": 1563000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T14:51:42", + "duration": 5877000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T16:29:39", + "duration": 10800000, + "percent": 1.4, + "rate": 0.91, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T18:00:00", + "duration": 10800000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T19:29:39", + "duration": 9021000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-15T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T18:00:00", + "duration": 813000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T18:13:33", + "duration": 18000000, + "percent": 1.65, + "rate": 1.89, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T22:00:00", + "duration": 18000000, + "percent": 1.65, + "rate": 2.39, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-16T23:13:33", + "duration": 2787000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-17T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T12:00:00", + "duration": 12800000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T15:33:20", + "duration": 256000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T15:37:36", + "duration": 8544000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-18T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T00:00:00", + "duration": 586000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T00:09:46", + "duration": 12600000, + "percent": 1.7, + "rate": 2.8, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T03:30:00", + "duration": 12600000, + "percent": 1.7, + "rate": 2.63, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T03:39:46", + "duration": 17414000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T12:00:00", + "duration": 17302000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T16:48:22", + "duration": 7200000, + "percent": 1.6, + "rate": 1.04, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T18:00:00", + "duration": 7200000, + "percent": 1.6, + "rate": 1.84, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T18:48:22", + "duration": 11498000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-19T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T12:00:00", + "duration": 19646000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T17:27:26", + "duration": 10800000, + "percent": 1.75, + "rate": 1.13, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T18:00:00", + "duration": 10800000, + "percent": 1.75, + "rate": 2.01, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T20:27:26", + "duration": 5554000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T22:00:00", + "duration": 3002000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T22:50:02", + "duration": 416000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-20T22:56:58", + "duration": 3782000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-21T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T12:00:00", + "duration": 11357000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T15:09:17", + "duration": 12600000, + "percent": 0.8, + "rate": 0.52, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T18:00:00", + "duration": 12600000, + "percent": 0.8, + "rate": 0.92, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T18:39:17", + "duration": 12043000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-22T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T08:30:00", + "duration": 9912000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T11:15:12", + "duration": 9000000, + "percent": 0.4, + "rate": 0.58, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T12:00:00", + "duration": 8340000, + "percent": 0.4, + "rate": 0.26, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T13:33:32", + "duration": 38000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T10:34:10", + "duration": 627000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T10:44:37", + "duration": 3600000, + "percent": 1.15, + "rate": 1.66, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.44, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T11:44:37", + "duration": 923000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T18:00:00", + "duration": 10191000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T20:49:51", + "duration": 12600000, + "percent": 1.4, + "rate": 1.61, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.15, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-23T22:00:00", + "duration": 12600000, + "percent": 1.4, + "rate": 2.03, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T00:00:00", + "duration": 12600000, + "percent": 1.4, + "rate": 2.31, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T00:19:51", + "duration": 11409000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T03:30:00", + "duration": 2088000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T04:04:48", + "duration": 20248000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T09:42:16", + "duration": 8264000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-24T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T12:00:00", + "duration": 7234000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T14:00:34", + "duration": 5400000, + "percent": 1.6, + "rate": 1.04, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T15:30:34", + "duration": 8966000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-25T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-26T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T03:30:00", + "duration": 16729000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:08:49", + "duration": 7200000, + "percent": 1.5, + "rate": 2.32, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.55, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T08:30:00", + "duration": 7200000, + "percent": 1.5, + "rate": 2.17, + "suppressed": { + "deliveryType": "scheduled", + "rate": 1.45, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T10:08:49", + "duration": 6671000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T12:00:00", + "duration": 65000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T12:01:05", + "duration": 421000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T12:08:06", + "duration": 21114000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-27T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-28T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-29T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T18:00:00", + "duration": 4889000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T19:21:29", + "duration": 14570000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-30T23:24:19", + "duration": 2141000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-10-31T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-01T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-02T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T03:30:00", + "duration": 13402000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T07:13:22", + "duration": 17773000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T12:09:35", + "duration": 5452000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "temp", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T13:40:27", + "duration": 9000000, + "percent": 1.5, + "rate": 0.97, + "suppressed": { + "deliveryType": "scheduled", + "rate": 0.65, + "scheduleName": "basal 3", + "type": "basal" + } + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T16:10:27", + "duration": 6573000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-03T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T03:30:00", + "duration": 6646000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T05:20:46", + "duration": 81000 + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T04:22:07", + "duration": 14873000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-04T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T18:00:00", + "duration": 14400000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-05T22:00:00", + "duration": 7200000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T00:00:00", + "duration": 12600000, + "rate": 1.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T03:30:00", + "duration": 18000000, + "rate": 1.55, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T08:30:00", + "duration": 12600000, + "rate": 1.45, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T12:00:00", + "duration": 21600000, + "rate": 0.65, + "scheduleName": "basal 3" + }, + { + "deliveryType": "scheduled", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T18:00:00", + "duration": 3581000, + "rate": 1.15, + "scheduleName": "basal 3" + }, + { + "annotations": [{ "code": "basal/unknown-duration" }], + "deliveryType": "suspend", + "deviceId": "some-pump", + "deviceTime": "2018-11-06T18:59:41", + "duration": 0 + } +] +` + +func GetPlatformBasalData() []map[string]interface{} { + data := []map[string]interface{}{} + json.Unmarshal([]byte(platformBasalStr), &data) + return data +} diff --git a/migrations/20231128_jellyfish_migration/verify/upload_blob.sh b/migrations/20231128_jellyfish_migration/verify/upload_blob.sh new file mode 100644 index 0000000000..7451909e6f --- /dev/null +++ b/migrations/20231128_jellyfish_migration/verify/upload_blob.sh @@ -0,0 +1,55 @@ +#!/bin/bash +BLOB_FILE=$1 +USER_EMAIL=$2 +USER_PW=$3 +UPLOADER_DIR=~/Documents/src/tidepool/uploader + +SCRIPT=$(realpath "$0") +BASE_DIR=$(dirname "$SCRIPT") + +check_val() { + if [[ -z "$1" ]]; then + echo "missing required '$2' value" + exit 2 + fi +} + +cd $UPLOADER_DIR + +source ./config/qa3.sh + +check_val $BLOB_FILE "BLOB_FILE" +check_val $USER_EMAIL "USER_EMAIL" +check_val $USER_PW "USER_PW" +check_val $API_URL "API_URL" +check_val $BASE_DIR "BASE_DIR" +check_val $UPLOADER_DIR "UPLOADER_DIR" + +start=$(date +%s) +SUCCESS=false +output='not yet run' + +if [[ "$BLOB_FILE" =~ .*"tandem".* ]]; then + output=$(node -r @babel/register lib/drivers/tandem/cli/loader.js loader.js -f $BLOB_FILE -u $USER_EMAIL -p $USER_PW) + echo "$output" | grep -q 'upload.toPlatform: all good' && SUCCESS=true +else + output=$(node -r @babel/register lib/drivers/insulet/cli/ibf_loader.js ibf_loader.js -f $BLOB_FILE -u $USER_EMAIL -p $USER_PW) + echo "$output" | grep -q 'upload.toPlatform: all good' && SUCCESS=true +fi + +cd $BASE_DIR + +end=$(date +%s) + +if [ "$SUCCESS" = true ]; then + echo 'upload all good' + records=$(echo "$output" | grep -A100000 'attempting to upload' | grep -B100000 'device data records') + runtime=$((end - start)) + echo "{'blob':'$BLOB_FILE', 'account':'$USER_EMAIL', 'time': '$runtime', 'records': '$records' }" >>blob_uploads.log + echo "$records" +else + echo 'upload failed!' + error_details=$(echo "$output" | grep -A100000 'platform add data to dataset failed.' | grep -B100000 'upload.toPlatform: failed') + echo "{'blob':'$BLOB_FILE', 'details':'{$error_details}'}" >>blob_errors.log + echo "$error_details" +fi diff --git a/migrations/20231128_jellyfish_migration/verify/utils_suite_test.go b/migrations/20231128_jellyfish_migration/verify/utils_suite_test.go new file mode 100644 index 0000000000..9700454fb2 --- /dev/null +++ b/migrations/20231128_jellyfish_migration/verify/utils_suite_test.go @@ -0,0 +1,11 @@ +package main_test + +import ( + "testing" + + "github.com/tidepool-org/platform/test" +) + +func TestSuite(t *testing.T) { + test.Test(t) +} diff --git a/migrations/20231128_jellyfish_migration/verify/verify.go b/migrations/20231128_jellyfish_migration/verify/verify.go index 45793097fd..029e3c58e5 100644 --- a/migrations/20231128_jellyfish_migration/verify/verify.go +++ b/migrations/20231128_jellyfish_migration/verify/verify.go @@ -7,11 +7,10 @@ import ( "os" "strings" + "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" "github.com/urfave/cli" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" - - "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" ) type Verify struct { @@ -19,7 +18,7 @@ type Verify struct { cli *cli.App config *config client *mongo.Client - verificationUtil *utils.DataVerify + verificationUtil *DataVerify } type config struct { @@ -69,7 +68,7 @@ func (m *Verify) RunAndExit() { defer m.client.Disconnect(m.ctx) if m.config.findBlobs { - m.verificationUtil, err = utils.NewVerifier( + m.verificationUtil, err = NewDataVerify( m.ctx, m.client.Database("data").Collection("deviceDataSets"), ) @@ -80,7 +79,7 @@ func (m *Verify) RunAndExit() { return m.verificationUtil.WriteBlobIDs() } - m.verificationUtil, err = utils.NewVerifier( + m.verificationUtil, err = NewDataVerify( m.ctx, m.client.Database("data").Collection("deviceData"), ) From 755103a26c8dc54fb71fa4b2e295aed480519386 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 30 Jul 2024 12:51:35 +1200 Subject: [PATCH 365/413] keep uploadId and _active --- .../20231128_jellyfish_migration/verify/data_verify.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/verify/data_verify.go b/migrations/20231128_jellyfish_migration/verify/data_verify.go index 3b6d5968d7..d3d36f3be0 100644 --- a/migrations/20231128_jellyfish_migration/verify/data_verify.go +++ b/migrations/20231128_jellyfish_migration/verify/data_verify.go @@ -85,7 +85,9 @@ func (m *DataVerify) fetchDataSet(uploadID string, dataTypes []string) (map[stri } excludedFeilds := bson.M{ - "_active": 0, + // include to check dedup + // "_active": 0, + // "uploadId": 0, "_archivedTime": 0, "createdTime": 0, "clockDriftOffset": 0, @@ -105,7 +107,6 @@ func (m *DataVerify) fetchDataSet(uploadID string, dataTypes []string) (map[stri "timezoneOffset": 0, "type": 0, "_userId": 0, - "uploadId": 0, "_version": 0, } From 820524081e76497874c4ebc08f3ad88ccde7d0ba Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 30 Jul 2024 14:52:05 +1200 Subject: [PATCH 366/413] cleanup and allow query of datasets for deduping --- .../utils/data_verify.go | 290 - .../utils/data_verify_test.go | 136 - .../utils/test/data_verify.go | 81405 ---------------- .../verify/data_verify.go | 66 +- .../verify/verify.go | 33 +- 5 files changed, 95 insertions(+), 81835 deletions(-) delete mode 100644 migrations/20231128_jellyfish_migration/utils/data_verify.go delete mode 100644 migrations/20231128_jellyfish_migration/utils/data_verify_test.go delete mode 100644 migrations/20231128_jellyfish_migration/utils/test/data_verify.go diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify.go b/migrations/20231128_jellyfish_migration/utils/data_verify.go deleted file mode 100644 index 55f815e9f6..0000000000 --- a/migrations/20231128_jellyfish_migration/utils/data_verify.go +++ /dev/null @@ -1,290 +0,0 @@ -package utils - -import ( - "context" - "errors" - "fmt" - "log" - "path/filepath" - - "github.com/r3labs/diff/v3" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" -) - -type DataVerify struct { - ctx context.Context - dataC *mongo.Collection -} - -func CompareDatasetDatums(platformData []map[string]interface{}, jellyfishData []map[string]interface{}, ignoredPaths ...string) (map[string]interface{}, error) { - diffs := map[string]interface{}{} - for id, platformDatum := range platformData { - if jellyfishData[id] == nil { - log.Println("no matching value in the jellyfish data") - break - } - changelog, err := diff.Diff(platformDatum, jellyfishData[id], diff.ConvertCompatibleTypes(), diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) - if err != nil { - return nil, err - } - if len(changelog) > 0 { - if ignoredPaths != nil { - for _, path := range ignoredPaths { - changelog = changelog.FilterOut([]string{path}) - } - if len(changelog) == 0 { - continue - } - } - diffs[fmt.Sprintf("platform_%d", id)] = changelog - } - } - return diffs, nil -} - -func NewVerifier(ctx context.Context, dataC *mongo.Collection) (*DataVerify, error) { - - if dataC == nil { - return nil, errors.New("missing required data collection") - } - - m := &DataVerify{ - ctx: ctx, - dataC: dataC, - } - - return m, nil -} - -var DatasetTypes = []string{"cbg", "smbg", "basal", "bolus", "deviceEvent", "wizard", "pumpSettings"} - -func (m *DataVerify) fetchDataSet(uploadID string, dataTypes []string) (map[string][]map[string]interface{}, error) { - if m.dataC == nil { - return nil, errors.New("missing data collection") - } - - typeSet := map[string][]map[string]interface{}{} - - for _, dType := range dataTypes { - - dset := []map[string]interface{}{} - - filter := bson.M{ - "uploadId": uploadID, - "type": dType, - } - - sort := bson.D{{Key: "time", Value: 1}} - - if dType == "deviceEvent" || dType == "bolus" { - sort = bson.D{{Key: "time", Value: 1}, {Key: "subType", Value: 1}} - } - - excludedFeilds := bson.M{ - "_active": 0, - "_archivedTime": 0, - "createdTime": 0, - "clockDriftOffset": 0, - "conversionOffset": 0, - "deduplicator": 0, - "_deduplicator": 0, - "_groupId": 0, - "guid": 0, - "_id": 0, - "id": 0, - "modifiedTime": 0, - "payload": 0, - "provenance": 0, - "revision": 0, - "_schemaVersion": 0, - "time": 0, - "timezoneOffset": 0, - "type": 0, - "_userId": 0, - "uploadId": 0, - "_version": 0, - } - - dDataCursor, err := m.dataC.Find(m.ctx, filter, &options.FindOptions{ - Sort: sort, - Projection: excludedFeilds, - }) - if err != nil { - return nil, err - } - defer dDataCursor.Close(m.ctx) - - if err := dDataCursor.All(m.ctx, &dset); err != nil { - return nil, err - } - log.Printf("got dataset [%s][%s][%d] results", uploadID, dType, len(dset)) - typeSet[dType] = dset - } - return typeSet, nil -} - -func (m *DataVerify) WriteBlobIDs() error { - if m.dataC == nil { - return errors.New("missing data collection") - } - - blobData := []map[string]interface{}{} - - dDataCursor, err := m.dataC.Find(m.ctx, bson.M{ - "deviceManufacturers": bson.M{"$in": []string{"Tandem", "Insulet"}}, - "client.private.blobId": bson.M{"$exists": true}, - "_active": true, - }, &options.FindOptions{ - Sort: bson.D{{Key: "deviceId", Value: 1}, {Key: "time", Value: 1}}, - Projection: bson.M{"_id": 0, "deviceId": 1, "blobId": "$client.private.blobId", "time": 1}, - }) - if err != nil { - return err - } - defer dDataCursor.Close(m.ctx) - - if err := dDataCursor.All(m.ctx, &blobData); err != nil { - return err - } - - type Blob struct { - DeviceID string `json:"deviceId"` - BlobID string `json:"blobId"` - } - - blobs := []Blob{} - - for _, v := range blobData { - blobs = append(blobs, Blob{ - BlobID: fmt.Sprintf("%v", v["blobId"]), - DeviceID: fmt.Sprintf("%v", v["deviceId"])}) - } - - blobPath := filepath.Join(".", "_blobs") - log.Printf("blob data written to %s", blobPath) - writeFileData(blobs, blobPath, "device_blobs.json", true) - return nil -} - -const ( - PlatformExtra = "extra" - PlatformDuplicate = "duplicate" - PlatformMissing = "missing" -) - -func CompareDatasets(platformSet []map[string]interface{}, jellyfishSet []map[string]interface{}) map[string][]map[string]interface{} { - - diffs := map[string][]map[string]interface{}{ - PlatformExtra: {}, - PlatformDuplicate: {}, - PlatformMissing: {}, - } - const deviceTimeName = "deviceTime" - type deviceTimeDatums map[string][]map[string]interface{} - - pfCounts := deviceTimeDatums{} - jfCounts := deviceTimeDatums{} - - for _, jDatum := range jellyfishSet { - strDatumTime := fmt.Sprintf("%v", jDatum[deviceTimeName]) - - if len(jfCounts[strDatumTime]) == 0 { - jfCounts[strDatumTime] = []map[string]interface{}{jDatum} - } else if len(jfCounts[strDatumTime]) >= 1 { - jfCounts[strDatumTime] = append(jfCounts[strDatumTime], jDatum) - } - } - - for _, pDatum := range platformSet { - - strDatumTime := fmt.Sprintf("%v", pDatum[deviceTimeName]) - - if len(pfCounts[strDatumTime]) == 0 { - pfCounts[strDatumTime] = []map[string]interface{}{pDatum} - } else if len(pfCounts[strDatumTime]) >= 1 { - - currentItems := pfCounts[strDatumTime] - for _, item := range currentItems { - if fmt.Sprintf("%v", item) == fmt.Sprintf("%v", pDatum) { - diffs[PlatformDuplicate] = append(diffs[PlatformDuplicate], pDatum) - continue - } else { - diffs[PlatformExtra] = append(diffs[PlatformExtra], pDatum) - break - } - } - pfCounts[strDatumTime] = append(pfCounts[strDatumTime], pDatum) - } - if len(jfCounts[fmt.Sprintf("%v", pDatum[deviceTimeName])]) == 0 { - diffs[PlatformExtra] = append(diffs[PlatformExtra], pDatum) - } - } - - for jfDeviceTimeStr, jDatums := range jfCounts { - if len(pfCounts[jfDeviceTimeStr]) < len(jfCounts[jfDeviceTimeStr]) { - //NOTE: more of an indicator there are missing records ... - for i := len(pfCounts[jfDeviceTimeStr]); i < len(jfCounts[jfDeviceTimeStr]); i++ { - diffs[PlatformMissing] = append(diffs[PlatformMissing], jDatums[i]) - } - } - } - return diffs -} - -var dataTypePathIgnored = map[string][]string{ - "smbg": {"raw", "value"}, - "cbg": {"value"}, - "basal": {"rate"}, - "bolus": {"normal"}, -} - -func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUploadID string, dataTyes []string) error { - - if len(dataTyes) == 0 { - dataTyes = DatasetTypes - } - - platformDataset, err := m.fetchDataSet(platformUploadID, dataTyes) - if err != nil { - return err - } - - jellyfishDataset, err := m.fetchDataSet(jellyfishUploadID, dataTyes) - if err != nil { - return err - } - - log.Printf("Compare platform[%s] vs jellyfish[%s]", platformUploadID, jellyfishUploadID) - - for dType, jfSet := range jellyfishDataset { - pfSet := platformDataset[dType] - comparePath := filepath.Join(".", "_compare", fmt.Sprintf("%s_%s", platformUploadID, jellyfishUploadID)) - log.Printf("data written to %s", comparePath) - setDifferences := CompareDatasets(pfSet, jfSet) - if len(setDifferences[PlatformMissing]) > 0 { - writeFileData(setDifferences[PlatformMissing], comparePath, fmt.Sprintf("%s_platform_missing.json", dType), true) - } - if len(setDifferences[PlatformDuplicate]) > 0 { - writeFileData(setDifferences[PlatformDuplicate], comparePath, fmt.Sprintf("%s_platform_duplicates.json", dType), true) - } - if len(setDifferences[PlatformExtra]) > 0 { - writeFileData(setDifferences[PlatformExtra], comparePath, fmt.Sprintf("%s_platform_extra.json", dType), true) - } - if len(pfSet) != len(jfSet) { - log.Printf("NOTE: datasets mismatch platform (%d) vs jellyfish (%d)", len(pfSet), len(jfSet)) - writeFileData(jfSet, comparePath, fmt.Sprintf("%s_jellyfish_datums.json", dType), true) - writeFileData(pfSet, comparePath, fmt.Sprintf("%s_platform_datums.json", dType), true) - break - } - differences, err := CompareDatasetDatums(pfSet, jfSet, dataTypePathIgnored[dType]...) - if err != nil { - return err - } - if len(differences) > 0 { - writeFileData(differences, comparePath, fmt.Sprintf("%s_datum_diff.json", dType), true) - } - } - return nil -} diff --git a/migrations/20231128_jellyfish_migration/utils/data_verify_test.go b/migrations/20231128_jellyfish_migration/utils/data_verify_test.go deleted file mode 100644 index 0a9b45c019..0000000000 --- a/migrations/20231128_jellyfish_migration/utils/data_verify_test.go +++ /dev/null @@ -1,136 +0,0 @@ -package utils_test - -import ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "github.com/r3labs/diff/v3" - - "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" - "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils/test" -) - -var _ = Describe("DataVerify", func() { - - var _ = Describe("CompareDatasetDatums", func() { - - var datasetOne = []map[string]interface{}{} - var datasetTwo = []map[string]interface{}{} - - BeforeEach(func() { - - datasetOne = []map[string]interface{}{ - { - "one": 1, - "value": 2, - }, - { - "three": 3, - "more": true, - }, - } - - datasetTwo = []map[string]interface{}{ - { - "one": "one", - "value": 2, - }, - { - "three": 3, - "more": false, - }, - } - - }) - - It("will genterate a list of differences between two datasets", func() { - changes, err := utils.CompareDatasetDatums(datasetOne, datasetTwo) - Expect(err).To(BeNil()) - Expect(changes).ToNot(BeEmpty()) - }) - - It("will genterate no differences when the datasets are the same ", func() { - changes, err := utils.CompareDatasetDatums(datasetOne, datasetOne) - Expect(err).To(BeNil()) - Expect(changes).To(BeEmpty()) - }) - - It("changes will contain each diff", func() { - changes, err := utils.CompareDatasetDatums(datasetOne, datasetTwo) - Expect(err).To(BeNil()) - Expect(changes).To(Equal(map[string]interface{}{ - "platform_0": diff.Changelog{{Type: diff.UPDATE, Path: []string{"one"}, From: 1, To: "one"}}, - "platform_1": diff.Changelog{{Type: diff.UPDATE, Path: []string{"more"}, From: true, To: false}}, - })) - }) - - It("can filter based on path", func() { - changes, err := utils.CompareDatasetDatums(datasetOne, datasetTwo, "more") - Expect(err).To(BeNil()) - Expect(changes).To(Equal(map[string]interface{}{ - "platform_0": diff.Changelog{{Type: diff.UPDATE, Path: []string{"one"}, From: 1, To: "one"}}, - })) - }) - - It("can filter multiple based on path", func() { - changes, err := utils.CompareDatasetDatums(datasetOne, datasetTwo, "more", "one") - Expect(err).To(BeNil()) - Expect(changes).To(BeEmpty()) - }) - - }) - var _ = Describe("CompareDatasets", func() { - - It("will have no differences when that same and no dups", func() { - dSetDifference := utils.CompareDatasets(test.JFBolusSet, test.JFBolusSet) - Expect(len(dSetDifference[utils.PlatformDuplicate])).To(Equal(0)) - Expect(len(dSetDifference[utils.PlatformExtra])).To(Equal(0)) - Expect(len(dSetDifference[utils.PlatformMissing])).To(Equal(0)) - }) - - It("will find duplicates in the platform dataset", func() { - dSetDifference := utils.CompareDatasets(test.PlatformBolusSet, test.JFBolusSet) - Expect(len(dSetDifference[utils.PlatformDuplicate])).To(Equal(395)) - Expect(len(dSetDifference[utils.PlatformExtra])).To(Equal(0)) - Expect(len(dSetDifference[utils.PlatformMissing])).To(Equal(0)) - }) - - It("will find extras in the platform dataset that have duplicate timestamp but not data", func() { - duplicateTimeStamp := map[string]interface{}{ - "extra": true, - "deviceTime": "2018-01-03T13:07:10", - } - - dSetDifference := utils.CompareDatasets(append(test.PlatformBolusSet, duplicateTimeStamp), test.JFBolusSet) - Expect(len(dSetDifference[utils.PlatformDuplicate])).To(Equal(395)) - Expect(len(dSetDifference[utils.PlatformExtra])).To(Equal(1)) - Expect(len(dSetDifference[utils.PlatformMissing])).To(Equal(0)) - }) - - It("will find extras in the platform dataset", func() { - expectedExtra := map[string]interface{}{ - "extra": 3, - "deviceTime": "2023-01-18T12:00:00", - } - - dSetDifference := utils.CompareDatasets(append(test.PlatformBolusSet, expectedExtra), test.JFBolusSet) - Expect(len(dSetDifference[utils.PlatformDuplicate])).To(Equal(395)) - Expect(len(dSetDifference[utils.PlatformExtra])).To(Equal(1)) - Expect(dSetDifference[utils.PlatformExtra][0]).To(Equal(expectedExtra)) - Expect(len(dSetDifference[utils.PlatformMissing])).To(Equal(0)) - }) - - It("will find datums that are missing in the platform dataset", func() { - platformBasals := test.GetPlatformBasalData() - jellyfishBasals := test.GetJFBasalData() - - Expect(len(platformBasals)).To(Equal(3123)) - Expect(len(jellyfishBasals)).To(Equal(3386)) - - dSetDifference := utils.CompareDatasets(platformBasals, jellyfishBasals) - Expect(len(dSetDifference[utils.PlatformDuplicate])).To(Equal(5)) - Expect(len(dSetDifference[utils.PlatformExtra])).To(Equal(4)) - Expect(len(dSetDifference[utils.PlatformMissing])).To(Equal(263)) - }) - - }) -}) diff --git a/migrations/20231128_jellyfish_migration/utils/test/data_verify.go b/migrations/20231128_jellyfish_migration/utils/test/data_verify.go deleted file mode 100644 index a089143b96..0000000000 --- a/migrations/20231128_jellyfish_migration/utils/test/data_verify.go +++ /dev/null @@ -1,81405 +0,0 @@ -package test - -import "encoding/json" - -var JFBolusSet = []map[string]interface{}{ - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T05:48:32", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T08:48:43", - "normal": 2.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T17:07:35", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T17:48:17", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T22:16:32", - "expectedNormal": 6, - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T02:48:01", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T02:57:56", - "normal": 2.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T03:45:23", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T04:02:33", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T04:07:54", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T12:10:52", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T13:43:31", - "normal": 0.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T18:55:53", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T22:06:00", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-13T00:07:54", - "normal": 6.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-13T15:36:15", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-13T19:15:32", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-13T23:32:46", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-14T02:56:18", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-14T15:05:16", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-14T18:45:59", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-14T21:06:30", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T02:10:44", - "expectedNormal": 6, - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T10:11:52", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T10:21:08", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T10:52:13", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T18:51:32", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T20:32:07", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T20:43:33", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T21:26:55", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T07:56:57", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T15:32:09", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:04:19", - "expectedNormal": 3.7, - "normal": 0.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:04:45", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:23:41", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:35:34", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:58:46", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T22:04:48", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T07:49:22", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T07:58:22", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T08:31:44", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T09:25:59", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T15:19:35", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T15:41:16", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T16:13:32", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T16:51:39", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T17:36:34", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T22:24:30", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T00:26:16", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T00:57:05", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T09:39:10", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T13:26:16", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T15:56:31", - "normal": 0.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T16:46:24", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T17:16:59", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T01:21:09", - "normal": 2.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T01:51:44", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T18:01:16", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T19:01:35", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T22:24:42", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T22:27:54", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T23:16:39", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T11:50:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T13:36:40", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T18:31:12", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T19:04:49", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T19:13:53", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-21T14:16:39", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T00:12:03", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T13:54:39", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T20:02:33", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T20:09:02", - "normal": 7.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T20:42:46", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T20:51:20", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-23T14:51:38", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-23T17:40:56", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T10:57:40", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T13:49:15", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T20:29:08", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T23:20:14", - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T02:11:25", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T03:41:15", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T03:49:26", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T11:34:54", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T11:36:30", - "expectedNormal": 3.7, - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T11:39:54", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T18:55:44", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T21:00:32", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T21:56:23", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T22:40:16", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T00:47:19", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T11:19:24", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T18:22:46", - "normal": 9.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T20:06:31", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T21:00:39", - "normal": 4.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T00:43:11", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T00:54:23", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T01:21:34", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T07:02:47", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T08:20:19", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T11:57:25", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T18:36:04", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T20:18:11", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T10:55:51", - "normal": 10.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T13:31:27", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T17:47:15", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T18:58:25", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T20:20:09", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T05:47:36", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T11:04:51", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T11:17:10", - "expectedNormal": 5, - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T11:17:44", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T11:59:21", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T12:33:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T16:04:51", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T18:22:02", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T20:35:15", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T00:19:10", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T01:14:53", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T11:38:04", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T14:10:30", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T18:11:40", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T19:40:37", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T22:39:58", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T09:55:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T12:02:23", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T12:11:07", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T15:03:11", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T23:36:08", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-02T13:42:27", - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T08:36:32", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T12:46:16", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T14:31:00", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T19:01:03", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T19:13:12", - "duration": 3600000, - "extended": 1.35, - "normal": 3.25, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T23:09:17", - "expectedNormal": 5.6, - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-04T01:32:34", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-04T13:31:48", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-04T23:45:20", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-05T05:38:22", - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-05T13:05:36", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-05T18:04:44", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-05T22:31:49", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-06T09:05:49", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-06T19:44:34", - "normal": 3.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-07T11:30:47", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-07T17:39:58", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T09:36:46", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T12:09:06", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T13:51:33", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T22:47:22", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T23:06:37", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T23:34:05", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T11:51:03", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T18:28:48", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T18:41:43", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T19:46:42", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T22:41:34", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T03:05:28", - "normal": 1.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T11:34:38", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T14:55:50", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T15:23:08", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T19:28:56", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T21:16:11", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T22:17:25", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-11T14:30:42", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-11T19:17:18", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T13:15:43", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T14:37:19", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T20:45:23", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T21:17:50", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T22:07:50", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T23:57:33", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-13T10:28:04", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-13T17:42:12", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T04:31:16", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T09:40:01", - "normal": 3.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T15:57:40", - "normal": 2.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T17:26:58", - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T05:49:43", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T09:42:54", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T15:42:11", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T17:58:05", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T20:36:40", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T21:54:57", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T02:10:54", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T05:18:35", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T17:03:43", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T21:17:40", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T21:27:12", - "expectedNormal": 1.8, - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-17T15:02:37", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-18T08:53:51", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-18T14:07:21", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-19T00:37:12", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-20T22:52:22", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-21T16:04:44", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-21T17:31:36", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-22T20:34:13", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T00:32:29", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T02:01:53", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T13:25:12", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T14:45:29", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T15:17:41", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T15:27:27", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T20:51:42", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T22:28:05", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-24T15:45:49", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-24T17:30:54", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T03:24:31", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T17:51:24", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T18:17:02", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T18:44:42", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T19:06:09", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-26T04:38:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-26T21:52:20", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-26T22:10:35", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T00:35:55", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T12:09:08", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T13:12:31", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T22:06:04", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T23:57:59", - "normal": 8.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T13:41:05", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T21:53:48", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T22:38:58", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T23:35:34", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T01:10:10", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T13:28:49", - "normal": 7.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T15:31:09", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T15:47:25", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T20:49:26", - "normal": 10.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T23:31:22", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T01:14:51", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T10:07:54", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T14:41:41", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T15:36:28", - "normal": 0.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T17:21:07", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T17:47:07", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T19:43:22", - "normal": 10.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T21:42:19", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T23:34:45", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T23:57:13", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T14:15:24", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T15:37:20", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T16:37:23", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T20:22:35", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T22:50:28", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T00:18:37", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T03:28:56", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T08:23:20", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T17:09:58", - "normal": 5.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T20:29:55", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T21:39:29", - "normal": 11.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T01:37:45", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T09:05:27", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T09:28:02", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T15:17:44", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T17:05:07", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T21:57:29", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T22:31:41", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T23:58:14", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T06:23:16", - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T13:07:10", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T17:36:24", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T19:19:53", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-04T20:39:32", - "normal": 12.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-04T23:27:30", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-05T11:26:40", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-05T14:39:47", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-05T21:24:08", - "normal": 12.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-05T23:47:57", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-06T10:29:13", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-07T02:43:11", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-07T15:29:23", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-07T15:53:38", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T00:50:58", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T02:22:40", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T10:49:22", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T12:10:15", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T16:06:15", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T21:00:55", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T22:52:11", - "normal": 13.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T06:48:05", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T11:57:20", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T14:50:09", - "expectedNormal": 7.1, - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T15:09:57", - "expectedNormal": 5.3, - "normal": 0, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T15:10:07", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T15:45:24", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T19:08:06", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T00:20:48", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T09:57:07", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T15:19:38", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T19:51:35", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T21:04:03", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-11T17:21:27", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-11T23:50:01", - "normal": 9.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-12T14:21:27", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T01:22:50", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T09:16:42", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T09:45:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T17:59:12", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T19:51:42", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T01:09:36", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T15:27:34", - "normal": 6.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T15:37:30", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T19:52:15", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T22:44:38", - "normal": 11, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T23:04:59", - "expectedNormal": 8.7, - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-15T08:08:01", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-15T17:50:26", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-15T18:22:34", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-15T22:12:43", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-16T05:28:57", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-16T19:06:03", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-18T00:44:27", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-18T15:16:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-18T21:34:19", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-19T15:18:48", - "normal": 7.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-19T18:24:25", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-19T21:40:18", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T01:57:09", - "normal": 5.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T05:21:15", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T14:43:26", - "normal": 2.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T20:23:29", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T23:15:21", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-21T01:47:25", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-21T16:32:58", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-21T21:12:41", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-22T13:07:23", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-22T13:24:37", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-22T13:38:43", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-22T14:23:46", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T00:01:17", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T02:53:10", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T10:26:09", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T12:45:53", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T19:04:33", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T02:03:30", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T08:42:05", - "normal": 3.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T09:11:28", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T13:05:25", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T16:20:41", - "normal": 0.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T19:39:24", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T22:58:57", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-25T09:05:32", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-25T09:15:49", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-25T10:05:32", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-25T15:20:46", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-26T00:34:00", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-26T00:40:32", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-26T17:42:21", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-27T00:26:46", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-27T01:56:53", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-27T15:00:57", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-27T16:30:36", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T00:07:24", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T04:04:35", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T11:06:58", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T12:05:56", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T17:32:14", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T22:51:31", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-29T09:24:11", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-29T11:48:49", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-31T17:35:53", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-01T22:39:45", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-01T23:11:22", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-02T05:32:22", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-02T13:53:59", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-02T15:01:02", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-03T11:47:19", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-03T17:52:13", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-04T00:51:30", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-04T01:35:03", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-04T10:23:28", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-05T00:40:31", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-05T22:10:18", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T00:30:31", - "duration": 9000000, - "extended": 2.4, - "normal": 0.1, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T11:27:46", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T12:24:47", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T21:00:06", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T21:26:09", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T22:30:08", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-07T01:20:24", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-07T15:08:42", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-07T17:35:21", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T00:40:52", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T04:05:56", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T04:08:07", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T20:24:34", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T21:17:19", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-09T03:41:21", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-09T03:43:00", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-09T15:27:27", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-09T16:50:23", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-10T00:06:05", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-10T07:13:02", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-10T10:23:08", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T01:16:30", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T13:20:10", - "normal": 1.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T17:04:18", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T19:38:24", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T20:40:19", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T22:22:57", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T23:03:25", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T10:31:15", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T10:47:00", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T17:15:24", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T22:52:54", - "duration": 5400000, - "extended": 3.6, - "normal": 0.4, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T23:37:16", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-13T03:06:20", - "expectedNormal": 2.4, - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-13T04:51:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-13T19:40:33", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-13T20:05:03", - "normal": 0.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-14T17:20:11", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-14T17:56:34", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-15T01:56:38", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-15T17:29:22", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-16T09:23:19", - "normal": 2.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-17T11:56:27", - "normal": 0.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T00:34:51", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T04:32:23", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T12:15:36", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T12:56:37", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T20:43:52", - "normal": 9.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T03:06:10", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T17:37:52", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T18:33:24", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T22:24:06", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T23:15:16", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T23:57:50", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T11:27:44", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T12:13:32", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T17:12:58", - "normal": 7.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T23:25:38", - "normal": 4.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-21T18:12:48", - "normal": 4.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-21T23:02:43", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-22T05:11:08", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-22T12:46:46", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-22T18:44:55", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-22T23:47:30", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-23T15:22:30", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T01:28:13", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T04:50:59", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T10:06:16", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T10:57:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T16:20:38", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T20:57:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T21:10:06", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T01:46:05", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T03:01:41", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T12:45:34", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T16:35:50", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T16:43:09", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-26T14:50:38", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-26T23:18:20", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-27T19:10:37", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-27T19:56:05", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-27T20:05:22", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-27T20:33:26", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-01T11:06:45", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-01T13:38:00", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-01T17:26:06", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T05:10:59", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T14:53:50", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T15:15:41", - "duration": 7200000, - "extended": 4, - "normal": 2.65, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T17:55:24", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T21:27:07", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-03T02:23:28", - "normal": 3.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-03T07:55:24", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-03T13:31:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-03T17:33:40", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T01:00:34", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T09:51:54", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T13:59:53", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T14:53:15", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T17:26:51", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T19:38:13", - "normal": 8.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T23:09:52", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T23:57:26", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-05T03:09:50", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-05T14:54:46", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-05T18:29:31", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-06T00:34:35", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-06T01:21:36", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-06T06:12:45", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-06T19:38:19", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T08:26:18", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T10:24:27", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T16:59:43", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T22:10:21", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T23:47:40", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-08T00:47:32", - "duration": 10800000, - "extended": 1.65, - "subType": "square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-08T17:20:24", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-08T23:16:45", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-09T09:43:12", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-09T19:36:18", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-09T21:47:07", - "normal": 11, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-09T22:28:29", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T00:56:27", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T05:18:33", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T10:09:03", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T19:08:41", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T19:30:42", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T21:00:08", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T21:11:26", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T00:12:25", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T03:50:32", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T09:48:55", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T17:56:25", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T21:45:42", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T23:48:21", - "normal": 7.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T23:59:24", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-12T11:02:19", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-12T14:13:44", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-12T23:30:03", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-13T00:01:21", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-13T08:23:02", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-13T15:29:58", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-13T16:25:10", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T01:00:14", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T01:48:33", - "duration": 7200000, - "extended": 5, - "subType": "square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T08:26:33", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T09:15:40", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T21:17:36", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T21:36:42", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T01:00:44", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T12:10:00", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T13:36:53", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T21:24:43", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T22:46:02", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-16T19:49:33", - "normal": 12.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-17T15:56:01", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-18T10:02:04", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-18T15:29:15", - "normal": 6.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-18T16:27:25", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-18T21:15:02", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-19T06:28:44", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-19T15:28:25", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-19T22:15:08", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T08:14:49", - "duration": 3600000, - "extended": 1.5, - "normal": 0.5, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T12:02:19", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T13:19:06", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T16:07:19", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T19:43:27", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T20:56:53", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-21T00:32:48", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-21T14:39:05", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-21T21:09:21", - "normal": 12, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-21T22:14:04", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T03:19:52", - "expectedNormal": 5.15, - "normal": 0.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T03:20:35", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T10:57:48", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T16:15:49", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T23:32:14", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T03:44:48", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T10:03:49", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T12:03:21", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T12:08:31", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T17:28:19", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T18:10:06", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T22:45:10", - "normal": 6.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T23:57:11", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T01:52:51", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T04:04:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T10:09:10", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T15:22:15", - "normal": 9.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T15:59:21", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T18:45:12", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T03:44:15", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T04:12:56", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T13:25:50", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T15:47:08", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T16:27:53", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T17:26:51", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T01:03:51", - "normal": 9.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T04:48:39", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T15:52:08", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T18:11:28", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T21:42:00", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T23:21:43", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-27T13:11:38", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-27T13:27:58", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-27T13:43:12", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-27T14:19:41", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-28T01:21:26", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-28T02:49:55", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-28T12:09:39", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-28T21:12:56", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T01:42:57", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T12:10:07", - "normal": 8.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T20:29:43", - "normal": 8.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T23:08:20", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T23:23:56", - "expectedNormal": 2, - "normal": 0.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T23:24:13", - "expectedNormal": 3.8, - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T23:25:03", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-30T09:17:33", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-30T11:41:40", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-30T18:46:16", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-30T22:26:35", - "normal": 7.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-31T09:34:04", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-31T11:02:09", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-31T18:03:31", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-01T13:35:12", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-01T19:00:43", - "expectedNormal": 5.5, - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-02T11:24:01", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T00:24:02", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T04:46:03", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T13:58:14", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T15:41:52", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T22:48:16", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T22:53:19", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T23:37:06", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T17:49:44", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T18:25:58", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T20:06:51", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T20:50:31", - "expectedNormal": 6.5, - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T21:47:42", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T11:10:22", - "normal": 8.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T13:57:52", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T14:41:02", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T19:55:35", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T20:07:23", - "normal": 6.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T23:10:52", - "normal": 10.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-06T17:04:13", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T00:30:35", - "normal": 13, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T11:30:23", - "expectedNormal": 11.3, - "normal": 7.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T13:39:36", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T15:31:20", - "normal": 7.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T17:03:27", - "normal": 6.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T19:36:38", - "normal": 11.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T02:04:38", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T11:36:22", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T15:35:43", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T16:36:54", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T17:06:19", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T18:36:43", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T20:45:53", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T21:43:56", - "normal": 5.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T22:27:26", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-09T13:34:32", - "normal": 4.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-09T23:51:42", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T11:33:52", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T15:06:31", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T16:39:01", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T23:28:10", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T23:56:06", - "normal": 3.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-11T08:31:34", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-11T14:14:04", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-11T21:33:10", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-12T13:11:06", - "normal": 5.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-12T15:22:32", - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-12T20:37:48", - "duration": 3600000, - "extended": 1.4, - "normal": 4.1, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T07:00:52", - "normal": 2.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T11:55:34", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T15:38:33", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T16:43:21", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T22:25:40", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T23:43:31", - "duration": 3600000, - "extended": 3, - "normal": 4.5, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T07:24:30", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T11:26:07", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T14:02:33", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T16:13:29", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T16:21:37", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-15T04:30:42", - "normal": 2.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-15T11:27:28", - "normal": 9.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-15T21:09:40", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-15T21:29:47", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T08:42:28", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T09:08:02", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T18:50:11", - "normal": 7.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T22:19:29", - "normal": 8.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T07:49:58", - "expectedNormal": 6.25, - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T10:22:10", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T15:38:57", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T16:53:15", - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T23:01:44", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T23:17:46", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-18T03:36:54", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-18T08:15:40", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-18T13:03:08", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-18T22:49:11", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-19T10:49:57", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-19T12:47:07", - "normal": 7.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-19T18:51:49", - "normal": 0.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T00:34:12", - "normal": 4.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T11:55:56", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T12:21:25", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T12:25:59", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T12:40:44", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T16:51:52", - "normal": 5.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T17:13:53", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T18:53:57", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T21:13:02", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T21:17:28", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T22:56:20", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T05:00:30", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T14:57:12", - "expectedNormal": 5.7, - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T17:25:57", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T19:55:14", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T20:21:02", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T20:48:12", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T23:36:01", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T00:17:02", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T07:20:00", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T09:32:51", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T15:34:54", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T17:17:07", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T18:33:33", - "normal": 8.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T19:56:36", - "normal": 4.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T21:38:22", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T14:44:27", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T16:39:55", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T17:17:36", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T18:45:04", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T21:54:57", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T23:08:34", - "expectedNormal": 2.5, - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T23:30:54", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T10:55:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T16:10:07", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T18:45:06", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T21:29:29", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-25T02:05:38", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-25T16:31:35", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-25T16:52:59", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-25T23:23:29", - "normal": 9.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T10:15:03", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T13:15:18", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T13:53:04", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T15:43:54", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T20:06:36", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-27T12:42:46", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-27T15:48:19", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-27T15:53:18", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-27T23:14:39", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T02:49:38", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T14:15:39", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T15:36:19", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T17:22:40", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T23:33:46", - "normal": 6.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-29T12:43:56", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-29T14:24:57", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-29T16:00:35", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-29T22:51:00", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-30T16:41:59", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-30T23:51:20", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-01T00:40:06", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-01T02:19:29", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-01T15:47:28", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-01T17:58:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T01:01:32", - "duration": 5400000, - "extended": 1.85, - "normal": 0.05, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T14:35:54", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T16:30:55", - "normal": 1.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T18:03:13", - "normal": 2.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T18:30:32", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T22:44:03", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-03T13:28:40", - "normal": 7.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-03T22:38:40", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T06:40:11", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T12:09:02", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T12:42:38", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T13:58:04", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T19:31:20", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-05T13:12:58", - "normal": 5.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-05T17:02:00", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-05T22:18:24", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-06T12:34:16", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-06T20:28:21", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-06T21:05:28", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-07T10:11:40", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-07T12:47:09", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-07T20:59:51", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-07T21:46:06", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-08T07:29:03", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-08T13:44:00", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-08T20:00:38", - "normal": 2.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-09T14:28:06", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-09T23:50:14", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T10:13:12", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T12:28:54", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T14:38:18", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T18:48:40", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T19:22:11", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T20:10:02", - "normal": 0.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T20:43:41", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T02:11:06", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T15:22:52", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T19:51:32", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T20:01:17", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T21:07:27", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T22:40:53", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T00:51:28", - "normal": 5.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T09:31:50", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T17:24:32", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T17:31:58", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T19:20:54", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T20:09:19", - "normal": 6.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T23:53:39", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T06:04:08", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T09:33:30", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T10:02:35", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T13:25:22", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T14:39:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T21:27:31", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T21:49:54", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-14T06:30:45", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-14T17:13:50", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-14T19:51:30", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T02:59:12", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T18:34:17", - "normal": 8.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T20:03:48", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T20:13:10", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T21:08:56", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T21:38:31", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T11:44:10", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T13:54:41", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T17:33:07", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T18:59:52", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T22:40:06", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T10:47:43", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T17:33:07", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T21:09:30", - "normal": 8.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T21:38:23", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-18T14:40:29", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-18T16:20:15", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-18T17:18:29", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-18T21:04:49", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T08:29:53", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T10:55:07", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T13:03:51", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T20:15:44", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T20:28:37", - "normal": 10.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T00:18:39", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T01:24:17", - "normal": 0.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T07:49:45", - "normal": 0.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T11:51:55", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T12:13:22", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T14:57:44", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T18:03:00", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T10:31:41", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T13:57:19", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T19:23:59", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T22:46:23", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-22T09:51:09", - "normal": 9.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-22T19:41:23", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-22T22:49:19", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T07:43:22", - "normal": 5.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T15:05:51", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T16:43:30", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T20:24:21", - "normal": 10.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T20:36:41", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T01:31:04", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T12:17:15", - "normal": 4.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T13:52:54", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T22:00:26", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T22:31:42", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T07:08:36", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T09:25:26", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T10:43:07", - "duration": 3600000, - "extended": 2.15, - "normal": 6.35, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T15:29:54", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T19:28:58", - "normal": 4.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T21:48:56", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T07:47:05", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T15:09:57", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T15:23:19", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T19:21:32", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T22:54:32", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T08:07:50", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T12:47:09", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T13:23:20", - "normal": 1.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T17:55:40", - "normal": 7.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T19:30:40", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T22:57:00", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T02:25:19", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T16:54:27", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T17:18:04", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T19:15:15", - "normal": 6.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T20:51:16", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T23:10:50", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-29T01:18:06", - "normal": 1.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-29T14:47:42", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-29T16:34:10", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-29T22:26:32", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T04:03:49", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T10:56:21", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T13:27:12", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T19:41:58", - "normal": 2.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T21:08:12", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T22:40:45", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T23:11:40", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-01T11:33:30", - "normal": 2.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-01T20:49:42", - "normal": 5.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-01T23:31:41", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T02:42:26", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T03:08:32", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T12:36:04", - "normal": 7.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T13:23:44", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T20:07:26", - "normal": 7.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T15:01:33", - "normal": 0.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T15:46:39", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T16:41:33", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T17:18:38", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T17:43:38", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T10:16:53", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T14:50:00", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T16:14:19", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T19:21:41", - "normal": 8.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T23:46:41", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T00:44:34", - "expectedNormal": 2, - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T01:02:58", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T12:01:09", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T12:23:18", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T12:51:54", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T15:39:48", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T21:29:36", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-06T04:21:34", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-06T08:53:58", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-07T15:08:48", - "normal": 0.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T19:54:26", - "normal": 7.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-08T15:53:04", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-08T22:22:31", - "normal": 7.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-08T22:47:20", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-09T15:51:36", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T00:59:27", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T10:23:36", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T18:30:44", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T18:39:41", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T19:47:34", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-11T13:53:18", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-11T20:58:05", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T00:35:54", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T13:04:51", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T17:37:35", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T19:09:48", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T19:34:40", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T00:02:43", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T00:11:41", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T08:33:39", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T20:19:52", - "duration": 1800000, - "extended": 2.55, - "normal": 0.6, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-14T16:44:31", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-14T22:46:55", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-15T00:28:57", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-15T08:51:33", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-15T11:33:53", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-15T19:09:51", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-16T17:02:11", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-16T18:49:50", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-16T20:22:02", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-17T11:14:04", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-17T19:29:27", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T06:45:25", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T15:28:35", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T16:20:17", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T16:50:44", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T22:16:57", - "duration": 3600000, - "extended": 4.2, - "normal": 2.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-19T07:18:23", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-19T18:51:48", - "normal": 4.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T08:50:29", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T11:19:38", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T15:42:53", - "duration": 1800000, - "extended": 0.45, - "normal": 1.3, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T17:25:24", - "duration": 3600000, - "extended": 0.75, - "normal": 3, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T21:38:30", - "duration": 3600000, - "extended": 2.85, - "normal": 6.55, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T11:54:08", - "duration": 3600000, - "extended": 2.8, - "normal": 2.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T14:39:04", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T18:23:31", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T19:29:16", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T20:00:12", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T21:40:40", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T23:42:55", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T00:24:30", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T08:20:59", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T21:37:44", - "duration": 3600000, - "extended": 1.2, - "normal": 4.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T22:25:47", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T23:37:05", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T07:32:39", - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T19:09:07", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T20:27:18", - "duration": 3600000, - "extended": 1.75, - "normal": 3.25, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T22:28:35", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T23:23:04", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T08:19:28", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T09:04:06", - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T10:00:56", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T18:30:46", - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T19:44:10", - "normal": 1.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T20:32:30", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T20:39:38", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T09:17:23", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T16:59:11", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T17:49:12", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T19:55:43", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-26T03:01:17", - "normal": 1.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-26T07:05:35", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-26T09:44:50", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-27T16:48:06", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-27T17:13:45", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-27T17:57:18", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-27T22:06:32", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-28T15:46:44", - "normal": 6.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-28T16:18:13", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-28T16:23:18", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-28T16:28:41", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-29T18:27:23", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-30T12:43:51", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-01T17:46:55", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-01T18:30:32", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-01T18:51:38", - "normal": 4.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-02T00:15:19", - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-02T06:49:58", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-02T18:35:00", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T12:03:51", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T12:50:24", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T17:08:12", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T17:41:00", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T19:08:04", - "expectedNormal": 2, - "normal": 0.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T19:08:18", - "normal": 0.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T01:21:22", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T14:10:31", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T17:59:30", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T19:21:37", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T19:25:51", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T20:09:01", - "normal": 7.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T02:02:39", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T02:36:40", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T13:58:30", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T17:17:54", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T23:40:50", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-06T01:28:33", - "normal": 3.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-06T14:59:11", - "normal": 2.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-06T20:26:50", - "duration": 3600000, - "extended": 2, - "normal": 6, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-07T00:48:50", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-07T14:09:43", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-07T16:02:12", - "duration": 5400000, - "extended": 3.25, - "normal": 9.75, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T18:17:26", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T18:29:06", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T20:29:43", - "normal": 5.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T23:53:16", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-09T12:19:24", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-09T16:27:30", - "duration": 3600000, - "extended": 1, - "normal": 5.65, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-09T17:50:34", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-10T00:25:49", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-10T17:43:21", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-10T18:08:03", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-11T13:06:32", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-11T19:37:52", - "normal": 7.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T00:07:01", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T00:42:51", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T07:40:06", - "normal": 3.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T08:50:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T16:09:42", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T21:45:57", - "normal": 6.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T10:56:43", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T11:42:47", - "normal": 1.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T16:33:50", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T18:21:41", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T22:13:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T22:19:30", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T22:48:14", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T23:08:30", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T14:31:41", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T15:53:20", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T17:37:39", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T18:15:11", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T20:29:30", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T12:18:56", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T14:09:52", - "normal": 4.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T17:23:04", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T21:15:01", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T21:44:35", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T22:12:37", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T22:57:20", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T22:58:49", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T09:35:57", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T11:31:07", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T15:12:49", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T15:41:21", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T21:04:38", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-17T03:22:39", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-17T14:09:57", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-17T16:29:43", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T05:26:35", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T08:03:17", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T17:58:39", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T20:40:22", - "duration": 1800000, - "extended": 5.7, - "normal": 1.9, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T08:36:08", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T15:20:39", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T18:22:28", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T18:54:15", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T22:20:06", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T22:47:22", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-20T14:23:03", - "duration": 3600000, - "extended": 1.35, - "normal": 5.4, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-20T15:02:15", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-20T15:50:21", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-21T00:08:35", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-21T12:12:24", - "normal": 5.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-21T15:13:53", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-22T16:11:14", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T01:06:51", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T10:37:02", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T16:18:09", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T16:57:31", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T21:30:01", - "duration": 1800000, - "extended": 3.55, - "normal": 1.15, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T08:03:19", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T13:21:49", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T13:41:26", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T15:13:42", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T17:30:34", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T18:47:01", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-25T00:37:32", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-25T15:27:34", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-25T15:50:46", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-25T18:34:45", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-26T08:00:02", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-26T15:30:21", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-26T16:43:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-26T22:55:06", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-27T00:34:23", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-27T16:08:38", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T10:22:34", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T10:42:12", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T11:14:05", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T12:22:02", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T17:58:24", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T00:59:10", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T13:21:48", - "normal": 3.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T14:26:37", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T15:29:23", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T19:11:00", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T21:59:18", - "duration": 10800000, - "extended": 8.65, - "normal": 2.85, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T07:29:04", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T11:32:41", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T13:33:42", - "normal": 2.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T15:10:57", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T16:48:04", - "duration": 2700000, - "expectedDuration": 3600000, - "expectedExtended": 2.65, - "extended": 1.95, - "normal": 4.5, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T17:35:25", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T06:01:14", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T08:02:24", - "expectedNormal": 1.8, - "normal": 0, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T17:32:27", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T19:24:54", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T20:15:14", - "normal": 7.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T23:11:02", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-01T15:38:03", - "normal": 7.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-02T00:53:24", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-02T09:42:56", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-02T12:33:40", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T13:13:56", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T13:30:33", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T19:02:46", - "normal": 7.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T23:23:36", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T23:30:48", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-04T07:57:10", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-04T17:05:51", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-04T18:14:03", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-05T16:45:27", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-05T19:47:08", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T09:25:42", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T15:20:44", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T16:19:31", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T17:07:49", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T19:58:23", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T14:38:43", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T19:47:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T20:51:30", - "normal": 8.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T21:31:38", - "normal": 5.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T01:05:38", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T10:11:09", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T15:43:17", - "normal": 6.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T19:52:56", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T20:57:40", - "duration": 3600000, - "extended": 2, - "normal": 8.95, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-09T09:07:47", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-09T16:17:45", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-09T17:24:45", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T01:12:55", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T18:24:34", - "normal": 5.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T19:04:48", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T20:30:46", - "normal": 0.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-12T10:04:06", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-13T17:30:51", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-13T18:15:01", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-13T18:43:29", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-14T15:37:44", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T01:47:54", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T13:59:56", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T14:41:43", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T14:44:38", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T21:54:18", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T15:51:57", - "normal": 7.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T16:23:22", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T20:59:44", - "normal": 7.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T22:28:09", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T13:43:39", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T15:22:58", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T20:43:00", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T22:37:07", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T12:51:55", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T15:37:39", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T16:20:47", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T16:23:34", - "expectedNormal": 1, - "normal": 0, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T16:23:47", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T01:18:52", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T18:35:04", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T18:45:16", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T19:19:18", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T19:49:49", - "normal": 9.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-20T13:23:57", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-20T18:56:03", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-21T18:29:04", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-21T20:46:21", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-22T21:10:05", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-22T21:58:04", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-22T22:02:55", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-23T18:27:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-23T20:31:41", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-23T20:59:54", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-23T23:21:11", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-24T10:24:29", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-24T17:07:32", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-24T17:33:08", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-24T18:35:51", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-25T14:07:13", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-25T17:12:17", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-25T21:24:58", - "normal": 8.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T11:35:34", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T11:48:12", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T12:08:19", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T16:13:11", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T22:12:41", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T01:27:13", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T16:56:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T19:56:41", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T20:22:28", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T20:57:07", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T07:42:06", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T09:05:30", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T09:54:05", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T14:01:25", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T15:50:43", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T20:59:49", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T21:29:58", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T01:28:07", - "expectedNormal": 3, - "normal": 0, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T01:28:23", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T05:09:40", - "expectedNormal": 2.55, - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T05:18:26", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T06:58:48", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T07:02:43", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T13:23:14", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T21:18:42", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-30T15:27:04", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-30T15:45:46", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-30T16:03:48", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-30T21:27:24", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-31T00:32:49", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-31T14:12:55", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T00:10:43", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T00:20:00", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T01:11:31", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T18:11:06", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T18:59:49", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T23:21:40", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T01:17:05", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T07:22:03", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T09:19:07", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T15:32:12", - "duration": 3600000, - "extended": 1.65, - "normal": 3.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T17:09:29", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T19:39:58", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T20:38:24", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T20:44:02", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T21:40:20", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T00:20:40", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T06:42:57", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T14:08:27", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T14:48:55", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T17:14:46", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T22:34:31", - "normal": 5.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-04T00:28:34", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-04T06:09:22", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-04T14:45:39", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-04T18:24:53", - "normal": 10.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-05T01:06:54", - "normal": 6.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-05T16:22:33", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-05T16:58:48", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-05T21:45:50", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T00:55:25", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T15:41:42", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T15:45:31", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T16:47:53", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T21:15:40", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-07T19:12:03", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-07T19:57:42", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-07T20:27:57", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-07T23:09:54", - "normal": 10.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T06:49:54", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T13:38:14", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T19:03:48", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T21:12:03", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T22:21:55", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-09T01:19:46", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-09T15:05:45", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-09T22:54:59", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-09T23:26:51", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T16:45:44", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T17:22:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T20:02:24", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T22:48:01", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T23:18:10", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-11T17:11:53", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-11T23:15:24", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-12T00:04:13", - "normal": 2.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-12T00:28:22", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-12T15:21:56", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-13T15:59:02", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-13T22:06:29", - "normal": 6.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-14T11:11:32", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-14T13:09:35", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-14T19:24:39", - "normal": 10.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-15T15:36:19", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-15T21:46:47", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-15T22:10:16", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-16T15:44:33", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-16T21:36:53", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-17T15:59:12", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-17T16:08:56", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-17T21:09:25", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-18T09:37:49", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-18T18:20:54", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-18T18:51:09", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-19T13:27:26", - "duration": 3600000, - "extended": 0.55, - "normal": 0.25, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-19T14:53:40", - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-19T15:24:30", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-20T18:32:41", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-20T21:29:36", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-21T15:35:49", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-21T21:03:52", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-21T22:39:49", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T11:25:56", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T13:19:40", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T17:25:35", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T19:59:31", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T22:50:19", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T11:45:40", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T11:47:49", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T12:07:32", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T15:08:45", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T20:33:01", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T22:00:40", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T06:08:59", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T08:33:59", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T11:22:33", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T21:52:26", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T22:08:46", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-25T16:52:46", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-25T20:23:33", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-25T20:36:44", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T07:18:20", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T10:15:04", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T16:11:43", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T19:25:09", - "normal": 6.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T21:22:26", - "normal": 1.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T12:14:07", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T13:57:02", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T14:09:20", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T15:29:54", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T20:48:41", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T21:12:09", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T21:20:49", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T21:49:25", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T04:50:11", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T07:40:45", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T12:06:19", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T15:46:19", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T21:47:01", - "normal": 12.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T01:12:35", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T02:08:17", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T02:59:26", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T14:42:33", - "normal": 7.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T15:02:43", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T15:12:10", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T19:10:18", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T19:46:49", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T11:29:40", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T13:56:15", - "normal": 5.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T15:42:59", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T22:53:22", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T23:05:22", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T23:35:16", - "normal": 7.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-01T14:27:43", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-01T16:04:42", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-01T22:28:45", - "normal": 6.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-02T17:01:12", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-02T18:18:32", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-02T22:08:17", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-02T22:56:37", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T07:44:00", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T08:42:58", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T15:24:28", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T17:53:59", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T19:00:37", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T22:17:33", - "normal": 7.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-04T09:52:11", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-04T12:55:58", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-04T15:12:11", - "normal": 6.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-04T20:09:22", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-05T03:27:19", - "normal": 4.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-05T19:22:47", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-05T22:39:45", - "normal": 10.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T06:12:37", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T12:42:06", - "normal": 8.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T15:32:00", - "expectedNormal": 4.7, - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T19:07:20", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T19:39:58", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-07T00:20:47", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-07T05:30:49", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-07T08:21:15", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-07T22:44:14", - "normal": 8.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-08T06:58:25", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-08T08:16:59", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-08T13:52:10", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-08T19:52:08", - "normal": 5.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T06:26:22", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T07:43:04", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T15:08:46", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T15:54:44", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T23:03:47", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T23:38:04", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-10T16:02:43", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-10T22:56:35", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-10T23:35:59", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-11T15:03:25", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-11T16:13:04", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-11T21:19:03", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T07:22:58", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T15:16:54", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T15:54:25", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T21:11:04", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T13:15:55", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T13:18:43", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T16:26:19", - "normal": 6.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T20:33:47", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T20:49:06", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T21:24:48", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T23:18:40", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T23:45:17", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T00:25:53", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T01:10:52", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T12:00:00", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T15:36:08", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T16:01:10", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T19:58:59", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T20:51:48", - "normal": 8.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T21:40:26", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T23:14:13", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T00:33:52", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T08:45:17", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T15:49:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T21:53:25", - "normal": 8.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T22:38:18", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-16T16:47:33", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-16T22:22:47", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-16T23:27:48", - "normal": 14.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-17T15:50:12", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-17T15:52:31", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T14:12:19", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T15:09:54", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T15:27:12", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T15:57:46", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T23:28:05", - "normal": 8.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T00:10:14", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T00:46:24", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T01:11:02", - "normal": 5.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T14:59:14", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T16:28:00", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T22:00:22", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T23:24:34", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T17:39:33", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T19:27:43", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T20:07:49", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T20:43:12", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T21:54:33", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-21T14:16:42", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-21T20:42:35", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-22T12:14:12", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T07:12:15", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T11:12:32", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T12:36:16", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T12:50:53", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T14:17:09", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-24T10:47:06", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-24T14:20:06", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-24T16:11:40", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-25T00:18:43", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-25T19:12:42", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-25T20:42:26", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-26T18:49:01", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-27T18:11:11", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-27T20:47:51", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-28T13:28:57", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-28T13:31:35", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-28T13:43:39", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-28T18:08:08", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-29T03:56:45", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-29T15:09:37", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-29T15:58:27", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-30T02:57:09", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-30T16:34:05", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-30T19:17:07", - "expectedNormal": 8, - "normal": 6.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-30T23:28:05", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-31T20:19:12", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-01T16:10:05", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-01T23:01:05", - "normal": 3.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-02T17:16:10", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-02T23:46:20", - "normal": 8.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-03T12:56:37", - "normal": 6.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-03T13:09:30", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-03T16:07:02", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-03T20:10:25", - "duration": 3600000, - "extended": 2.2, - "normal": 12.3, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T05:00:38", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T12:35:17", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T15:46:38", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T22:01:14", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-05T09:37:58", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-05T13:19:18", - "normal": 2, - "subType": "normal", - }, -} - -var PlatformBolusSet = []map[string]interface{}{ - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T05:48:32", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T05:48:32", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T08:48:43", - "normal": 2.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T08:48:43", - "normal": 2.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T17:07:35", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T17:48:17", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T22:16:32", - "expectedNormal": 6, - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T02:48:01", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T02:57:56", - "normal": 2.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T02:57:56", - "normal": 2.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T03:45:23", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T04:02:33", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T04:02:33", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T04:07:54", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T12:10:52", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T12:10:52", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T13:43:31", - "normal": 0.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T13:43:31", - "normal": 0.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T18:55:53", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T22:06:00", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-13T00:07:54", - "normal": 6.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-13T15:36:15", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-13T15:36:15", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-13T19:15:32", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-13T23:32:46", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-14T02:56:18", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-14T15:05:16", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-14T15:05:16", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-14T18:45:59", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-14T21:06:30", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T02:10:44", - "expectedNormal": 6, - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T10:11:52", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T10:21:08", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T10:52:13", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T18:51:32", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T20:32:07", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T20:43:33", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T20:43:33", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T21:26:55", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T07:56:57", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T07:56:57", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T15:32:09", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T15:32:09", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:04:19", - "expectedNormal": 3.7, - "normal": 0.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:04:45", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:23:41", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:35:34", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:58:46", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T22:04:48", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T07:49:22", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T07:49:22", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T07:58:22", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T08:31:44", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T09:25:59", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T15:19:35", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T15:41:16", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T16:13:32", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T16:51:39", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T17:36:34", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T22:24:30", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T00:26:16", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T00:57:05", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T09:39:10", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T13:26:16", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T15:56:31", - "normal": 0.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T15:56:31", - "normal": 0.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T16:46:24", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T17:16:59", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T17:16:59", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T01:21:09", - "normal": 2.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T01:21:09", - "normal": 2.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T01:51:44", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T18:01:16", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T19:01:35", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T22:24:42", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T22:27:54", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T23:16:39", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T11:50:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T13:36:40", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T13:36:40", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T18:31:12", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T19:04:49", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T19:13:53", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-21T14:16:39", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T00:12:03", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T00:12:03", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T13:54:39", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T20:02:33", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T20:09:02", - "normal": 7.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T20:42:46", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T20:51:20", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-23T14:51:38", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-23T14:51:38", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-23T17:40:56", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T10:57:40", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T13:49:15", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T13:49:15", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T20:29:08", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T20:29:08", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T23:20:14", - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T23:20:14", - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T02:11:25", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T02:11:25", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T03:41:15", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T03:49:26", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T11:34:54", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T11:36:30", - "expectedNormal": 3.7, - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T11:39:54", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T18:55:44", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T21:00:32", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T21:56:23", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T22:40:16", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T00:47:19", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T11:19:24", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T11:19:24", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T18:22:46", - "normal": 9.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T18:22:46", - "normal": 9.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T20:06:31", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T21:00:39", - "normal": 4.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T00:43:11", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T00:54:23", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T01:21:34", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T01:21:34", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T07:02:47", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T08:20:19", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T08:20:19", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T11:57:25", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T18:36:04", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T20:18:11", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T10:55:51", - "normal": 10.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T13:31:27", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T17:47:15", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T18:58:25", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T20:20:09", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T05:47:36", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T11:04:51", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T11:17:10", - "expectedNormal": 5, - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T11:17:44", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T11:59:21", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T11:59:21", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T12:33:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T16:04:51", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T18:22:02", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T18:22:02", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T20:35:15", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T00:19:10", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T01:14:53", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T11:38:04", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T11:38:04", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T14:10:30", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T18:11:40", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T19:40:37", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T22:39:58", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T09:55:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T12:02:23", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T12:02:23", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T12:11:07", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T15:03:11", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T23:36:08", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-02T13:42:27", - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-02T13:42:27", - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T08:36:32", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T12:46:16", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T14:31:00", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T19:01:03", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T19:13:12", - "duration": 3600000, - "extended": 1.35, - "normal": 3.25, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T19:13:12", - "duration": 3600000, - "extended": 1.35, - "normal": 3.25, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T23:09:17", - "expectedNormal": 5.6, - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T23:09:17", - "expectedNormal": 5.6, - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-04T01:32:34", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-04T13:31:48", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-04T23:45:20", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-05T05:38:22", - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-05T05:38:22", - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-05T13:05:36", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-05T18:04:44", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-05T22:31:49", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-06T09:05:49", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-06T19:44:34", - "normal": 3.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-06T19:44:34", - "normal": 3.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-07T11:30:47", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-07T17:39:58", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T09:36:46", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T09:36:46", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T12:09:06", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T13:51:33", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T13:51:33", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T22:47:22", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T23:06:37", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T23:34:05", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T11:51:03", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T18:28:48", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T18:41:43", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T19:46:42", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T19:46:42", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T22:41:34", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T03:05:28", - "normal": 1.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T03:05:28", - "normal": 1.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T11:34:38", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T14:55:50", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T15:23:08", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T19:28:56", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T21:16:11", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T22:17:25", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-11T14:30:42", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-11T19:17:18", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T13:15:43", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T14:37:19", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T20:45:23", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T21:17:50", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T22:07:50", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T23:57:33", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T23:57:33", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-13T10:28:04", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-13T10:28:04", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-13T17:42:12", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T04:31:16", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T09:40:01", - "normal": 3.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T09:40:01", - "normal": 3.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T15:57:40", - "normal": 2.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T15:57:40", - "normal": 2.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T17:26:58", - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T17:26:58", - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T05:49:43", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T09:42:54", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T09:42:54", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T15:42:11", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T17:58:05", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T20:36:40", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T21:54:57", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T02:10:54", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T05:18:35", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T05:18:35", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T17:03:43", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T21:17:40", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T21:27:12", - "expectedNormal": 1.8, - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-17T15:02:37", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-17T15:02:37", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-18T08:53:51", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-18T08:53:51", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-18T14:07:21", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-18T14:07:21", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-19T00:37:12", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-20T22:52:22", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-20T22:52:22", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-21T16:04:44", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-21T16:04:44", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-21T17:31:36", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-22T20:34:13", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T00:32:29", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T00:32:29", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T02:01:53", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T02:01:53", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T13:25:12", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T14:45:29", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T14:45:29", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T15:17:41", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T15:27:27", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T20:51:42", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T20:51:42", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T22:28:05", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T22:28:05", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-24T15:45:49", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-24T15:45:49", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-24T17:30:54", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T03:24:31", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T17:51:24", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T18:17:02", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T18:44:42", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T19:06:09", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-26T04:38:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-26T21:52:20", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-26T22:10:35", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T00:35:55", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T12:09:08", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T13:12:31", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T22:06:04", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T23:57:59", - "normal": 8.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T23:57:59", - "normal": 8.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T13:41:05", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T13:41:05", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T21:53:48", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T21:53:48", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T22:38:58", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T23:35:34", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T01:10:10", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T13:28:49", - "normal": 7.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T15:31:09", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T15:47:25", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T20:49:26", - "normal": 10.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T20:49:26", - "normal": 10.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T23:31:22", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T01:14:51", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T01:14:51", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T10:07:54", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T14:41:41", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T14:41:41", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T15:36:28", - "normal": 0.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T15:36:28", - "normal": 0.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T17:21:07", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T17:47:07", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T17:47:07", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T19:43:22", - "normal": 10.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T21:42:19", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T23:34:45", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T23:57:13", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T14:15:24", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T15:37:20", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T16:37:23", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T20:22:35", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T22:50:28", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T00:18:37", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T03:28:56", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T08:23:20", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T17:09:58", - "normal": 5.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T17:09:58", - "normal": 5.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T20:29:55", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T21:39:29", - "normal": 11.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T21:39:29", - "normal": 11.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T01:37:45", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T01:37:45", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T09:05:27", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T09:05:27", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T09:28:02", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T09:28:02", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T15:17:44", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T15:17:44", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T17:05:07", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T21:57:29", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T21:57:29", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T22:31:41", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T23:58:14", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T23:58:14", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T06:23:16", - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T06:23:16", - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T13:07:10", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T13:07:10", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T17:36:24", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T17:36:24", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T19:19:53", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-04T20:39:32", - "normal": 12.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-04T23:27:30", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-05T11:26:40", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-05T14:39:47", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-05T21:24:08", - "normal": 12.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-05T23:47:57", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-06T10:29:13", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-07T02:43:11", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-07T15:29:23", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-07T15:53:38", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T00:50:58", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T02:22:40", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T10:49:22", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T12:10:15", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T16:06:15", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T21:00:55", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T22:52:11", - "normal": 13.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T06:48:05", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T11:57:20", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T14:50:09", - "expectedNormal": 7.1, - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T15:09:57", - "expectedNormal": 5.3, - "normal": 0, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T15:10:07", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T15:45:24", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T19:08:06", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T00:20:48", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T09:57:07", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T15:19:38", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T15:19:38", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T19:51:35", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T21:04:03", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-11T17:21:27", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-11T23:50:01", - "normal": 9.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-11T23:50:01", - "normal": 9.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-12T14:21:27", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T01:22:50", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T09:16:42", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T09:45:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T17:59:12", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T19:51:42", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T01:09:36", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T01:09:36", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T15:27:34", - "normal": 6.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T15:37:30", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T19:52:15", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T22:44:38", - "normal": 11, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T23:04:59", - "expectedNormal": 8.7, - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-15T08:08:01", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-15T08:08:01", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-15T17:50:26", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-15T18:22:34", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-15T22:12:43", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-16T05:28:57", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-16T19:06:03", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-18T00:44:27", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-18T00:44:27", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-18T15:16:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-18T21:34:19", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-19T15:18:48", - "normal": 7.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-19T15:18:48", - "normal": 7.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-19T18:24:25", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-19T21:40:18", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T01:57:09", - "normal": 5.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T01:57:09", - "normal": 5.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T05:21:15", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T14:43:26", - "normal": 2.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T14:43:26", - "normal": 2.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T20:23:29", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T23:15:21", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-21T01:47:25", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-21T01:47:25", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-21T16:32:58", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-21T16:32:58", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-21T21:12:41", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-22T13:07:23", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-22T13:24:37", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-22T13:38:43", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-22T13:38:43", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-22T14:23:46", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T00:01:17", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T02:53:10", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T10:26:09", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T12:45:53", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T19:04:33", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T02:03:30", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T02:03:30", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T08:42:05", - "normal": 3.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T08:42:05", - "normal": 3.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T09:11:28", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T13:05:25", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T16:20:41", - "normal": 0.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T16:20:41", - "normal": 0.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T19:39:24", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T22:58:57", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T22:58:57", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-25T09:05:32", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-25T09:15:49", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-25T10:05:32", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-25T15:20:46", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-26T00:34:00", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-26T00:40:32", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-26T17:42:21", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-27T00:26:46", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-27T01:56:53", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-27T15:00:57", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-27T16:30:36", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T00:07:24", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T04:04:35", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T11:06:58", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T12:05:56", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T17:32:14", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T22:51:31", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-29T09:24:11", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-29T11:48:49", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-31T17:35:53", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-01T22:39:45", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-01T23:11:22", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-02T05:32:22", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-02T13:53:59", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-02T15:01:02", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-03T11:47:19", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-03T17:52:13", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-04T00:51:30", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-04T01:35:03", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-04T10:23:28", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-05T00:40:31", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-05T22:10:18", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T00:30:31", - "duration": 9000000, - "extended": 2.4, - "normal": 0.1, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T00:30:31", - "duration": 9000000, - "extended": 2.4, - "normal": 0.1, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T11:27:46", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T12:24:47", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T12:24:47", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T21:00:06", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T21:26:09", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T22:30:08", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-07T01:20:24", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-07T01:20:24", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-07T15:08:42", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-07T17:35:21", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-07T17:35:21", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T00:40:52", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T00:40:52", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T04:05:56", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T04:08:07", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T20:24:34", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T21:17:19", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-09T03:41:21", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-09T03:43:00", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-09T15:27:27", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-09T15:27:27", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-09T16:50:23", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-10T00:06:05", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-10T07:13:02", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-10T10:23:08", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T01:16:30", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T13:20:10", - "normal": 1.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T13:20:10", - "normal": 1.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T17:04:18", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T19:38:24", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T20:40:19", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T22:22:57", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T23:03:25", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T10:31:15", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T10:47:00", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T17:15:24", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T22:52:54", - "duration": 5400000, - "extended": 3.6, - "normal": 0.4, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T22:52:54", - "duration": 5400000, - "extended": 3.6, - "normal": 0.4, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T23:37:16", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-13T03:06:20", - "expectedNormal": 2.4, - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-13T04:51:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-13T19:40:33", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-13T20:05:03", - "normal": 0.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-14T17:20:11", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-14T17:56:34", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-15T01:56:38", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-15T17:29:22", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-16T09:23:19", - "normal": 2.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-16T09:23:19", - "normal": 2.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-17T11:56:27", - "normal": 0.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-17T11:56:27", - "normal": 0.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T00:34:51", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T04:32:23", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T12:15:36", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T12:56:37", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T20:43:52", - "normal": 9.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T03:06:10", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T17:37:52", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T17:37:52", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T18:33:24", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T22:24:06", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T23:15:16", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T23:57:50", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T11:27:44", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T12:13:32", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T17:12:58", - "normal": 7.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T17:12:58", - "normal": 7.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T23:25:38", - "normal": 4.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T23:25:38", - "normal": 4.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-21T18:12:48", - "normal": 4.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-21T23:02:43", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-22T05:11:08", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-22T12:46:46", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-22T18:44:55", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-22T23:47:30", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-23T15:22:30", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T01:28:13", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T04:50:59", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T04:50:59", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T10:06:16", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T10:57:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T16:20:38", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T20:57:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T21:10:06", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T01:46:05", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T03:01:41", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T03:01:41", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T12:45:34", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T16:35:50", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T16:43:09", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-26T14:50:38", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-26T23:18:20", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-27T19:10:37", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-27T19:56:05", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-27T20:05:22", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-27T20:33:26", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-01T11:06:45", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-01T13:38:00", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-01T13:38:00", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-01T17:26:06", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T05:10:59", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T14:53:50", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T15:15:41", - "duration": 7200000, - "extended": 4, - "normal": 2.65, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T15:15:41", - "duration": 7200000, - "extended": 4, - "normal": 2.65, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T17:55:24", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T21:27:07", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T21:27:07", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-03T02:23:28", - "normal": 3.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-03T02:23:28", - "normal": 3.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-03T07:55:24", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-03T13:31:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-03T17:33:40", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T01:00:34", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T09:51:54", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T13:59:53", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T14:53:15", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T17:26:51", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T19:38:13", - "normal": 8.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T23:09:52", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T23:57:26", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T23:57:26", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-05T03:09:50", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-05T14:54:46", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-05T18:29:31", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-06T00:34:35", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-06T01:21:36", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-06T06:12:45", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-06T19:38:19", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T08:26:18", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T10:24:27", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T16:59:43", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T22:10:21", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T23:47:40", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-08T00:47:32", - "duration": 10800000, - "extended": 1.65, - "subType": "square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-08T00:47:32", - "duration": 10800000, - "extended": 1.65, - "subType": "square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-08T17:20:24", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-08T23:16:45", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-08T23:16:45", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-09T09:43:12", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-09T19:36:18", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-09T21:47:07", - "normal": 11, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-09T22:28:29", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T00:56:27", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T05:18:33", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T10:09:03", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T19:08:41", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T19:30:42", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T21:00:08", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T21:11:26", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T00:12:25", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T00:12:25", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T03:50:32", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T09:48:55", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T17:56:25", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T21:45:42", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T23:48:21", - "normal": 7.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T23:59:24", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-12T11:02:19", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-12T14:13:44", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-12T23:30:03", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-13T00:01:21", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-13T08:23:02", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-13T15:29:58", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-13T16:25:10", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T01:00:14", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T01:48:33", - "duration": 7200000, - "extended": 5, - "subType": "square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T08:26:33", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T09:15:40", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T21:17:36", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T21:36:42", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T01:00:44", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T12:10:00", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T13:36:53", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T21:24:43", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T22:46:02", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-16T19:49:33", - "normal": 12.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-16T19:49:33", - "normal": 12.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-17T15:56:01", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-17T15:56:01", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-18T10:02:04", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-18T15:29:15", - "normal": 6.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-18T15:29:15", - "normal": 6.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-18T16:27:25", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-18T21:15:02", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-19T06:28:44", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-19T15:28:25", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-19T22:15:08", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T08:14:49", - "duration": 3600000, - "extended": 1.5, - "normal": 0.5, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T12:02:19", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T13:19:06", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T16:07:19", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T19:43:27", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T20:56:53", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-21T00:32:48", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-21T14:39:05", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-21T21:09:21", - "normal": 12, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-21T22:14:04", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T03:19:52", - "expectedNormal": 5.15, - "normal": 0.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T03:19:52", - "expectedNormal": 5.15, - "normal": 0.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T03:20:35", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T10:57:48", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T16:15:49", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T23:32:14", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T03:44:48", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T10:03:49", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T12:03:21", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T12:03:21", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T12:08:31", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T17:28:19", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T18:10:06", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T22:45:10", - "normal": 6.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T23:57:11", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T01:52:51", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T04:04:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T10:09:10", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T15:22:15", - "normal": 9.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T15:59:21", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T18:45:12", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T03:44:15", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T04:12:56", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T13:25:50", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T15:47:08", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T16:27:53", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T16:27:53", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T17:26:51", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T01:03:51", - "normal": 9.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T01:03:51", - "normal": 9.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T04:48:39", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T15:52:08", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T18:11:28", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T21:42:00", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T23:21:43", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-27T13:11:38", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-27T13:27:58", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-27T13:43:12", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-27T14:19:41", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-28T01:21:26", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-28T02:49:55", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-28T02:49:55", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-28T12:09:39", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-28T21:12:56", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T01:42:57", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T12:10:07", - "normal": 8.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T12:10:07", - "normal": 8.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T20:29:43", - "normal": 8.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T20:29:43", - "normal": 8.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T23:08:20", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T23:23:56", - "expectedNormal": 2, - "normal": 0.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T23:24:13", - "expectedNormal": 3.8, - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T23:25:03", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-30T09:17:33", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-30T11:41:40", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-30T18:46:16", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-30T22:26:35", - "normal": 7.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-30T22:26:35", - "normal": 7.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-31T09:34:04", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-31T11:02:09", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-31T18:03:31", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-01T13:35:12", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-01T19:00:43", - "expectedNormal": 5.5, - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-02T11:24:01", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-02T11:24:01", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T00:24:02", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T00:24:02", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T04:46:03", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T13:58:14", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T15:41:52", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T22:48:16", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T22:48:16", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T22:53:19", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T23:37:06", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T17:49:44", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T18:25:58", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T20:06:51", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T20:50:31", - "expectedNormal": 6.5, - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T21:47:42", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T11:10:22", - "normal": 8.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T13:57:52", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T14:41:02", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T19:55:35", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T20:07:23", - "normal": 6.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T20:07:23", - "normal": 6.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T23:10:52", - "normal": 10.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T23:10:52", - "normal": 10.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-06T17:04:13", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T00:30:35", - "normal": 13, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T11:30:23", - "expectedNormal": 11.3, - "normal": 7.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T11:30:23", - "expectedNormal": 11.3, - "normal": 7.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T13:39:36", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T15:31:20", - "normal": 7.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T17:03:27", - "normal": 6.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T19:36:38", - "normal": 11.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T19:36:38", - "normal": 11.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T02:04:38", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T02:04:38", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T11:36:22", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T11:36:22", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T15:35:43", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T16:36:54", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T17:06:19", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T17:06:19", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T18:36:43", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T20:45:53", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T21:43:56", - "normal": 5.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T22:27:26", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T22:27:26", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-09T13:34:32", - "normal": 4.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-09T13:34:32", - "normal": 4.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-09T23:51:42", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T11:33:52", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T15:06:31", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T16:39:01", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T23:28:10", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T23:28:10", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T23:56:06", - "normal": 3.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T23:56:06", - "normal": 3.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-11T08:31:34", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-11T14:14:04", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-11T21:33:10", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-11T21:33:10", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-12T13:11:06", - "normal": 5.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-12T15:22:32", - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-12T15:22:32", - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-12T20:37:48", - "duration": 3600000, - "extended": 1.4, - "normal": 4.1, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-12T20:37:48", - "duration": 3600000, - "extended": 1.4, - "normal": 4.1, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T07:00:52", - "normal": 2.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T07:00:52", - "normal": 2.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T11:55:34", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T15:38:33", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T15:38:33", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T16:43:21", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T22:25:40", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T23:43:31", - "duration": 3600000, - "extended": 3, - "normal": 4.5, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T23:43:31", - "duration": 3600000, - "extended": 3, - "normal": 4.5, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T07:24:30", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T11:26:07", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T14:02:33", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T16:13:29", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T16:21:37", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-15T04:30:42", - "normal": 2.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-15T04:30:42", - "normal": 2.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-15T11:27:28", - "normal": 9.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-15T21:09:40", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-15T21:29:47", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T08:42:28", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T08:42:28", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T09:08:02", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T18:50:11", - "normal": 7.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T18:50:11", - "normal": 7.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T22:19:29", - "normal": 8.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T22:19:29", - "normal": 8.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T07:49:58", - "expectedNormal": 6.25, - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T07:49:58", - "expectedNormal": 6.25, - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T10:22:10", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T15:38:57", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T16:53:15", - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T16:53:15", - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T23:01:44", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T23:01:44", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T23:17:46", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-18T03:36:54", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-18T08:15:40", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-18T13:03:08", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-18T13:03:08", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-18T22:49:11", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-19T10:49:57", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-19T10:49:57", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-19T12:47:07", - "normal": 7.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-19T12:47:07", - "normal": 7.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-19T18:51:49", - "normal": 0.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-19T18:51:49", - "normal": 0.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T00:34:12", - "normal": 4.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T00:34:12", - "normal": 4.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T11:55:56", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T11:55:56", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T12:21:25", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T12:25:59", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T12:40:44", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T16:51:52", - "normal": 5.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T16:51:52", - "normal": 5.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T17:13:53", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T18:53:57", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T21:13:02", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T21:17:28", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T22:56:20", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T05:00:30", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T05:00:30", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T14:57:12", - "expectedNormal": 5.7, - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T17:25:57", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T19:55:14", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T20:21:02", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T20:48:12", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T23:36:01", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T00:17:02", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T07:20:00", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T07:20:00", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T09:32:51", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T15:34:54", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T17:17:07", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T18:33:33", - "normal": 8.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T19:56:36", - "normal": 4.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T21:38:22", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T14:44:27", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T16:39:55", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T17:17:36", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T18:45:04", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T21:54:57", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T23:08:34", - "expectedNormal": 2.5, - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T23:30:54", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T10:55:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T16:10:07", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T16:10:07", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T18:45:06", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T18:45:06", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T21:29:29", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-25T02:05:38", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-25T16:31:35", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-25T16:52:59", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-25T23:23:29", - "normal": 9.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-25T23:23:29", - "normal": 9.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T10:15:03", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T13:15:18", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T13:53:04", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T15:43:54", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T20:06:36", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-27T12:42:46", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-27T15:48:19", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-27T15:53:18", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-27T23:14:39", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T02:49:38", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T14:15:39", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T14:15:39", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T15:36:19", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T17:22:40", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T23:33:46", - "normal": 6.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-29T12:43:56", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-29T14:24:57", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-29T16:00:35", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-29T16:00:35", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-29T22:51:00", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-30T16:41:59", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-30T23:51:20", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-30T23:51:20", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-01T00:40:06", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-01T02:19:29", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-01T15:47:28", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-01T17:58:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-01T17:58:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T01:01:32", - "duration": 5400000, - "extended": 1.85, - "normal": 0.05, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T01:01:32", - "duration": 5400000, - "extended": 1.85, - "normal": 0.05, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T14:35:54", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T16:30:55", - "normal": 1.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T16:30:55", - "normal": 1.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T18:03:13", - "normal": 2.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T18:03:13", - "normal": 2.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T18:30:32", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T22:44:03", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-03T13:28:40", - "normal": 7.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-03T13:28:40", - "normal": 7.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-03T22:38:40", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-03T22:38:40", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T06:40:11", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T12:09:02", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T12:42:38", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T13:58:04", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T19:31:20", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T19:31:20", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-05T13:12:58", - "normal": 5.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-05T13:12:58", - "normal": 5.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-05T17:02:00", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-05T17:02:00", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-05T22:18:24", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-05T22:18:24", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-06T12:34:16", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-06T20:28:21", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-06T21:05:28", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-07T10:11:40", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-07T12:47:09", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-07T12:47:09", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-07T20:59:51", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-07T21:46:06", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-08T07:29:03", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-08T07:29:03", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-08T13:44:00", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-08T13:44:00", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-08T20:00:38", - "normal": 2.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-08T20:00:38", - "normal": 2.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-09T14:28:06", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-09T14:28:06", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-09T23:50:14", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T10:13:12", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T12:28:54", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T12:28:54", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T14:38:18", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T18:48:40", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T18:48:40", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T19:22:11", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T20:10:02", - "normal": 0.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T20:10:02", - "normal": 0.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T20:43:41", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T02:11:06", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T15:22:52", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T19:51:32", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T20:01:17", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T21:07:27", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T22:40:53", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T00:51:28", - "normal": 5.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T00:51:28", - "normal": 5.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T09:31:50", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T17:24:32", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T17:31:58", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T19:20:54", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T20:09:19", - "normal": 6.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T23:53:39", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T06:04:08", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T09:33:30", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T09:33:30", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T10:02:35", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T13:25:22", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T14:39:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T21:27:31", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T21:49:54", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T21:49:54", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-14T06:30:45", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-14T17:13:50", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-14T17:13:50", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-14T19:51:30", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T02:59:12", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T18:34:17", - "normal": 8.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T18:34:17", - "normal": 8.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T20:03:48", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T20:13:10", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T21:08:56", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T21:38:31", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T11:44:10", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T13:54:41", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T17:33:07", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T18:59:52", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T22:40:06", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T22:40:06", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T10:47:43", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T17:33:07", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T17:33:07", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T21:09:30", - "normal": 8.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T21:09:30", - "normal": 8.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T21:38:23", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T21:38:23", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-18T14:40:29", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-18T16:20:15", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-18T17:18:29", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-18T21:04:49", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-18T21:04:49", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T08:29:53", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T08:29:53", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T10:55:07", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T13:03:51", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T20:15:44", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T20:28:37", - "normal": 10.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T20:28:37", - "normal": 10.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T00:18:39", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T01:24:17", - "normal": 0.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T01:24:17", - "normal": 0.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T07:49:45", - "normal": 0.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T07:49:45", - "normal": 0.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T11:51:55", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T12:13:22", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T14:57:44", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T18:03:00", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T10:31:41", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T10:31:41", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T13:57:19", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T19:23:59", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T19:23:59", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T22:46:23", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-22T09:51:09", - "normal": 9.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-22T09:51:09", - "normal": 9.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-22T19:41:23", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-22T19:41:23", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-22T22:49:19", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T07:43:22", - "normal": 5.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T07:43:22", - "normal": 5.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T15:05:51", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T15:05:51", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T16:43:30", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T16:43:30", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T20:24:21", - "normal": 10.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T20:24:21", - "normal": 10.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T20:36:41", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T01:31:04", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T01:31:04", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T12:17:15", - "normal": 4.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T12:17:15", - "normal": 4.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T13:52:54", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T22:00:26", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T22:31:42", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T22:31:42", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T07:08:36", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T07:08:36", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T09:25:26", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T09:25:26", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T10:43:07", - "duration": 3600000, - "extended": 2.15, - "normal": 6.35, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T10:43:07", - "duration": 3600000, - "extended": 2.15, - "normal": 6.35, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T15:29:54", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T19:28:58", - "normal": 4.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T21:48:56", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T07:47:05", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T15:09:57", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T15:23:19", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T19:21:32", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T19:21:32", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T22:54:32", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T08:07:50", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T08:07:50", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T12:47:09", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T12:47:09", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T13:23:20", - "normal": 1.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T13:23:20", - "normal": 1.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T17:55:40", - "normal": 7.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T19:30:40", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T22:57:00", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T02:25:19", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T16:54:27", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T16:54:27", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T17:18:04", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T19:15:15", - "normal": 6.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T20:51:16", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T23:10:50", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-29T01:18:06", - "normal": 1.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-29T01:18:06", - "normal": 1.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-29T14:47:42", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-29T16:34:10", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-29T22:26:32", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T04:03:49", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T10:56:21", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T13:27:12", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T19:41:58", - "normal": 2.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T19:41:58", - "normal": 2.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T21:08:12", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T21:08:12", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T22:40:45", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T23:11:40", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-01T11:33:30", - "normal": 2.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-01T11:33:30", - "normal": 2.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-01T20:49:42", - "normal": 5.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-01T20:49:42", - "normal": 5.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-01T23:31:41", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T02:42:26", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T02:42:26", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T03:08:32", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T12:36:04", - "normal": 7.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T12:36:04", - "normal": 7.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T13:23:44", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T20:07:26", - "normal": 7.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T15:01:33", - "normal": 0.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T15:46:39", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T16:41:33", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T17:18:38", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T17:43:38", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T10:16:53", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T14:50:00", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T16:14:19", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T19:21:41", - "normal": 8.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T19:21:41", - "normal": 8.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T23:46:41", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T00:44:34", - "expectedNormal": 2, - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T01:02:58", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T12:01:09", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T12:01:09", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T12:23:18", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T12:51:54", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T15:39:48", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T15:39:48", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T21:29:36", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T21:29:36", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-06T04:21:34", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-06T04:21:34", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-06T08:53:58", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-06T08:53:58", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-07T15:08:48", - "normal": 0.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T19:54:26", - "normal": 7.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-08T15:53:04", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-08T15:53:04", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-08T22:22:31", - "normal": 7.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-08T22:47:20", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-09T15:51:36", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T00:59:27", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T00:59:27", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T10:23:36", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T18:30:44", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T18:39:41", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T18:39:41", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T19:47:34", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-11T13:53:18", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-11T20:58:05", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T00:35:54", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T13:04:51", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T17:37:35", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T19:09:48", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T19:09:48", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T19:34:40", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T00:02:43", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T00:11:41", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T00:11:41", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T08:33:39", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T20:19:52", - "duration": 1800000, - "extended": 2.55, - "normal": 0.6, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T20:19:52", - "duration": 1800000, - "extended": 2.55, - "normal": 0.6, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-14T16:44:31", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-14T16:44:31", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-14T22:46:55", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-15T00:28:57", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-15T08:51:33", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-15T11:33:53", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-15T19:09:51", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-16T17:02:11", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-16T17:02:11", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-16T18:49:50", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-16T20:22:02", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-17T11:14:04", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-17T19:29:27", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T06:45:25", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T15:28:35", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T16:20:17", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T16:50:44", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T22:16:57", - "duration": 3600000, - "extended": 4.2, - "normal": 2.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T22:16:57", - "duration": 3600000, - "extended": 4.2, - "normal": 2.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-19T07:18:23", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-19T18:51:48", - "normal": 4.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-19T18:51:48", - "normal": 4.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T08:50:29", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T11:19:38", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T11:19:38", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T15:42:53", - "duration": 1800000, - "extended": 0.45, - "normal": 1.3, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T15:42:53", - "duration": 1800000, - "extended": 0.45, - "normal": 1.3, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T17:25:24", - "duration": 3600000, - "extended": 0.75, - "normal": 3, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T17:25:24", - "duration": 3600000, - "extended": 0.75, - "normal": 3, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T21:38:30", - "duration": 3600000, - "extended": 2.85, - "normal": 6.55, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T21:38:30", - "duration": 3600000, - "extended": 2.85, - "normal": 6.55, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T11:54:08", - "duration": 3600000, - "extended": 2.8, - "normal": 2.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T14:39:04", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T14:39:04", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T18:23:31", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T19:29:16", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T20:00:12", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T20:00:12", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T21:40:40", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T23:42:55", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T00:24:30", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T08:20:59", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T08:20:59", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T21:37:44", - "duration": 3600000, - "extended": 1.2, - "normal": 4.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T21:37:44", - "duration": 3600000, - "extended": 1.2, - "normal": 4.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T22:25:47", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T23:37:05", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T23:37:05", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T07:32:39", - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T07:32:39", - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T19:09:07", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T20:27:18", - "duration": 3600000, - "extended": 1.75, - "normal": 3.25, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T22:28:35", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T23:23:04", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T08:19:28", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T08:19:28", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T09:04:06", - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T09:04:06", - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T10:00:56", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T10:00:56", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T18:30:46", - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T18:30:46", - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T19:44:10", - "normal": 1.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T19:44:10", - "normal": 1.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T20:32:30", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T20:39:38", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T20:39:38", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T09:17:23", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T16:59:11", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T16:59:11", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T17:49:12", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T19:55:43", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T19:55:43", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-26T03:01:17", - "normal": 1.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-26T03:01:17", - "normal": 1.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-26T07:05:35", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-26T09:44:50", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-26T09:44:50", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-27T16:48:06", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-27T17:13:45", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-27T17:57:18", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-27T22:06:32", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-27T22:06:32", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-28T15:46:44", - "normal": 6.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-28T15:46:44", - "normal": 6.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-28T16:18:13", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-28T16:23:18", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-28T16:28:41", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-29T18:27:23", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-29T18:27:23", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-30T12:43:51", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-30T12:43:51", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-01T17:46:55", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-01T17:46:55", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-01T18:30:32", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-01T18:51:38", - "normal": 4.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-01T18:51:38", - "normal": 4.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-02T00:15:19", - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-02T00:15:19", - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-02T06:49:58", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-02T06:49:58", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-02T18:35:00", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-02T18:35:00", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T12:03:51", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T12:50:24", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T17:08:12", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T17:41:00", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T17:41:00", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T19:08:04", - "expectedNormal": 2, - "normal": 0.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T19:08:18", - "normal": 0.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T01:21:22", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T14:10:31", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T14:10:31", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T17:59:30", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T17:59:30", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T19:21:37", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T19:21:37", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T19:25:51", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T20:09:01", - "normal": 7.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T20:09:01", - "normal": 7.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T02:02:39", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T02:02:39", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T02:36:40", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T13:58:30", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T13:58:30", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T17:17:54", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T17:17:54", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T23:40:50", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T23:40:50", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-06T01:28:33", - "normal": 3.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-06T01:28:33", - "normal": 3.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-06T14:59:11", - "normal": 2.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-06T14:59:11", - "normal": 2.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-06T20:26:50", - "duration": 3600000, - "extended": 2, - "normal": 6, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-06T20:26:50", - "duration": 3600000, - "extended": 2, - "normal": 6, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-07T00:48:50", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-07T14:09:43", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-07T16:02:12", - "duration": 5400000, - "extended": 3.25, - "normal": 9.75, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T18:17:26", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T18:29:06", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T20:29:43", - "normal": 5.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T20:29:43", - "normal": 5.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T23:53:16", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T23:53:16", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-09T12:19:24", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-09T12:19:24", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-09T16:27:30", - "duration": 3600000, - "extended": 1, - "normal": 5.65, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-09T16:27:30", - "duration": 3600000, - "extended": 1, - "normal": 5.65, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-09T17:50:34", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-10T00:25:49", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-10T17:43:21", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-10T18:08:03", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-11T13:06:32", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-11T19:37:52", - "normal": 7.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-11T19:37:52", - "normal": 7.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T00:07:01", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T00:07:01", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T00:42:51", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T07:40:06", - "normal": 3.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T07:40:06", - "normal": 3.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T08:50:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T16:09:42", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T21:45:57", - "normal": 6.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T21:45:57", - "normal": 6.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T10:56:43", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T11:42:47", - "normal": 1.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T11:42:47", - "normal": 1.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T16:33:50", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T18:21:41", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T22:13:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T22:19:30", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T22:48:14", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T23:08:30", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T14:31:41", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T15:53:20", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T17:37:39", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T18:15:11", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T20:29:30", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T12:18:56", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T14:09:52", - "normal": 4.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T14:09:52", - "normal": 4.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T17:23:04", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T17:23:04", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T21:15:01", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T21:44:35", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T22:12:37", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T22:57:20", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T22:58:49", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T09:35:57", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T11:31:07", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T15:12:49", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T15:41:21", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T21:04:38", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-17T03:22:39", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-17T03:22:39", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-17T14:09:57", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-17T16:29:43", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-17T16:29:43", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T05:26:35", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T05:26:35", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T08:03:17", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T17:58:39", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T20:40:22", - "duration": 1800000, - "extended": 5.7, - "normal": 1.9, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T20:40:22", - "duration": 1800000, - "extended": 5.7, - "normal": 1.9, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T08:36:08", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T15:20:39", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T18:22:28", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T18:54:15", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T22:20:06", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T22:47:22", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-20T14:23:03", - "duration": 3600000, - "extended": 1.35, - "normal": 5.4, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-20T14:23:03", - "duration": 3600000, - "extended": 1.35, - "normal": 5.4, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-20T15:02:15", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-20T15:50:21", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-21T00:08:35", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-21T00:08:35", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-21T12:12:24", - "normal": 5.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-21T12:12:24", - "normal": 5.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-21T15:13:53", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-21T15:13:53", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-22T16:11:14", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T01:06:51", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T01:06:51", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T10:37:02", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T16:18:09", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T16:18:09", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T16:57:31", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T21:30:01", - "duration": 1800000, - "extended": 3.55, - "normal": 1.15, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T21:30:01", - "duration": 1800000, - "extended": 3.55, - "normal": 1.15, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T08:03:19", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T13:21:49", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T13:41:26", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T15:13:42", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T17:30:34", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T18:47:01", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-25T00:37:32", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-25T15:27:34", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-25T15:50:46", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-25T18:34:45", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-25T18:34:45", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-26T08:00:02", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-26T15:30:21", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-26T15:30:21", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-26T16:43:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-26T22:55:06", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-27T00:34:23", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-27T16:08:38", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T10:22:34", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T10:42:12", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T11:14:05", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T12:22:02", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T12:22:02", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T17:58:24", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T00:59:10", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T13:21:48", - "normal": 3.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T13:21:48", - "normal": 3.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T14:26:37", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T14:26:37", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T15:29:23", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T19:11:00", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T21:59:18", - "duration": 10800000, - "extended": 8.65, - "normal": 2.85, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T21:59:18", - "duration": 10800000, - "extended": 8.65, - "normal": 2.85, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T07:29:04", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T11:32:41", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T11:32:41", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T13:33:42", - "normal": 2.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T13:33:42", - "normal": 2.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T15:10:57", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T16:48:04", - "duration": 2700000, - "expectedDuration": 3600000, - "expectedExtended": 2.65, - "extended": 1.95, - "normal": 4.5, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T16:48:04", - "duration": 2700000, - "expectedDuration": 3600000, - "expectedExtended": 2.65, - "extended": 1.95, - "normal": 4.5, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T17:35:25", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T06:01:14", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T08:02:24", - "expectedNormal": 1.8, - "normal": 0, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T17:32:27", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T17:32:27", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T19:24:54", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T20:15:14", - "normal": 7.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T20:15:14", - "normal": 7.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T23:11:02", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-01T15:38:03", - "normal": 7.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-02T00:53:24", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-02T00:53:24", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-02T09:42:56", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-02T12:33:40", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T13:13:56", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T13:13:56", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T13:30:33", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T19:02:46", - "normal": 7.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T19:02:46", - "normal": 7.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T23:23:36", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T23:30:48", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-04T07:57:10", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-04T17:05:51", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-04T18:14:03", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-05T16:45:27", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-05T19:47:08", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T09:25:42", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T15:20:44", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T16:19:31", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T17:07:49", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T19:58:23", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T19:58:23", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T14:38:43", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T19:47:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T20:51:30", - "normal": 8.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T20:51:30", - "normal": 8.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T21:31:38", - "normal": 5.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T21:31:38", - "normal": 5.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T01:05:38", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T10:11:09", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T15:43:17", - "normal": 6.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T15:43:17", - "normal": 6.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T19:52:56", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T20:57:40", - "duration": 3600000, - "extended": 2, - "normal": 8.95, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T20:57:40", - "duration": 3600000, - "extended": 2, - "normal": 8.95, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-09T09:07:47", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-09T16:17:45", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-09T17:24:45", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T01:12:55", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T18:24:34", - "normal": 5.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T18:24:34", - "normal": 5.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T19:04:48", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T20:30:46", - "normal": 0.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T20:30:46", - "normal": 0.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-12T10:04:06", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-13T17:30:51", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-13T18:15:01", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-13T18:15:01", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-13T18:43:29", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-14T15:37:44", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T01:47:54", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T13:59:56", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T14:41:43", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T14:44:38", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T21:54:18", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T15:51:57", - "normal": 7.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T15:51:57", - "normal": 7.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T16:23:22", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T20:59:44", - "normal": 7.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T20:59:44", - "normal": 7.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T22:28:09", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T13:43:39", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T15:22:58", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T20:43:00", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T20:43:00", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T22:37:07", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T22:37:07", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T12:51:55", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T15:37:39", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T15:37:39", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T16:20:47", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T16:23:34", - "expectedNormal": 1, - "normal": 0, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T16:23:47", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T01:18:52", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T18:35:04", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T18:35:04", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T18:45:16", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T19:19:18", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T19:49:49", - "normal": 9.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-20T13:23:57", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-20T13:23:57", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-20T18:56:03", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-20T18:56:03", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-21T18:29:04", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-21T18:29:04", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-21T20:46:21", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-21T20:46:21", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-22T21:10:05", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-22T21:58:04", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-22T22:02:55", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-23T18:27:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-23T18:27:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-23T20:31:41", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-23T20:59:54", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-23T23:21:11", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-24T10:24:29", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-24T17:07:32", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-24T17:33:08", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-24T18:35:51", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-25T14:07:13", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-25T17:12:17", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-25T21:24:58", - "normal": 8.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T11:35:34", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T11:48:12", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T12:08:19", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T16:13:11", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T22:12:41", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T01:27:13", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T16:56:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T19:56:41", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T20:22:28", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T20:57:07", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T07:42:06", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T07:42:06", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T09:05:30", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T09:05:30", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T09:54:05", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T09:54:05", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T14:01:25", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T15:50:43", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T20:59:49", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T21:29:58", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T01:28:07", - "expectedNormal": 3, - "normal": 0, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T01:28:23", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T05:09:40", - "expectedNormal": 2.55, - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T05:09:40", - "expectedNormal": 2.55, - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T05:18:26", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T05:18:26", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T06:58:48", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T07:02:43", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T13:23:14", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T21:18:42", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T21:18:42", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-30T15:27:04", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-30T15:45:46", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-30T16:03:48", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-30T21:27:24", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-31T00:32:49", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-31T00:32:49", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-31T14:12:55", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T00:10:43", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T00:20:00", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T01:11:31", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T18:11:06", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T18:59:49", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T18:59:49", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T23:21:40", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T01:17:05", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T07:22:03", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T09:19:07", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T15:32:12", - "duration": 3600000, - "extended": 1.65, - "normal": 3.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T15:32:12", - "duration": 3600000, - "extended": 1.65, - "normal": 3.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T17:09:29", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T19:39:58", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T19:39:58", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T20:38:24", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T20:38:24", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T20:44:02", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T21:40:20", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T00:20:40", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T00:20:40", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T06:42:57", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T14:08:27", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T14:48:55", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T17:14:46", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T22:34:31", - "normal": 5.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-04T00:28:34", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-04T06:09:22", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-04T14:45:39", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-04T18:24:53", - "normal": 10.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-05T01:06:54", - "normal": 6.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-05T16:22:33", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-05T16:58:48", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-05T21:45:50", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T00:55:25", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T15:41:42", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T15:45:31", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T16:47:53", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T21:15:40", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T21:15:40", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-07T19:12:03", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-07T19:57:42", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-07T20:27:57", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-07T23:09:54", - "normal": 10.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T06:49:54", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T13:38:14", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T19:03:48", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T21:12:03", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T22:21:55", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-09T01:19:46", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-09T15:05:45", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-09T22:54:59", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-09T23:26:51", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T16:45:44", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T17:22:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T20:02:24", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T22:48:01", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T23:18:10", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-11T17:11:53", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-11T23:15:24", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-12T00:04:13", - "normal": 2.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-12T00:04:13", - "normal": 2.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-12T00:28:22", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-12T15:21:56", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-13T15:59:02", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-13T22:06:29", - "normal": 6.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-14T11:11:32", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-14T13:09:35", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-14T19:24:39", - "normal": 10.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-14T19:24:39", - "normal": 10.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-15T15:36:19", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-15T21:46:47", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-15T21:46:47", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-15T22:10:16", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-16T15:44:33", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-16T21:36:53", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-17T15:59:12", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-17T16:08:56", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-17T21:09:25", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-17T21:09:25", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-18T09:37:49", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-18T18:20:54", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-18T18:51:09", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-19T13:27:26", - "duration": 3600000, - "extended": 0.55, - "normal": 0.25, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-19T13:27:26", - "duration": 3600000, - "extended": 0.55, - "normal": 0.25, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-19T14:53:40", - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-19T14:53:40", - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-19T15:24:30", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-20T18:32:41", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-20T21:29:36", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-21T15:35:49", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-21T15:35:49", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-21T21:03:52", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-21T22:39:49", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T11:25:56", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T13:19:40", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T17:25:35", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T19:59:31", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T22:50:19", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T11:45:40", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T11:47:49", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T12:07:32", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T15:08:45", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T20:33:01", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T22:00:40", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T06:08:59", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T08:33:59", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T11:22:33", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T21:52:26", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T22:08:46", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-25T16:52:46", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-25T20:23:33", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-25T20:36:44", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T07:18:20", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T10:15:04", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T16:11:43", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T19:25:09", - "normal": 6.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T21:22:26", - "normal": 1.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T21:22:26", - "normal": 1.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T12:14:07", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T13:57:02", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T14:09:20", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T15:29:54", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T20:48:41", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T21:12:09", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T21:20:49", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T21:49:25", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T04:50:11", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T07:40:45", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T12:06:19", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T15:46:19", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T15:46:19", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T21:47:01", - "normal": 12.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T21:47:01", - "normal": 12.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T01:12:35", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T02:08:17", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T02:59:26", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T14:42:33", - "normal": 7.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T14:42:33", - "normal": 7.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T15:02:43", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T15:12:10", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T19:10:18", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T19:46:49", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T11:29:40", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T13:56:15", - "normal": 5.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T15:42:59", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T22:53:22", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T23:05:22", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T23:35:16", - "normal": 7.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-01T14:27:43", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-01T16:04:42", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-01T22:28:45", - "normal": 6.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-01T22:28:45", - "normal": 6.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-02T17:01:12", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-02T17:01:12", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-02T18:18:32", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-02T22:08:17", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-02T22:56:37", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T07:44:00", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T08:42:58", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T15:24:28", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T15:24:28", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T17:53:59", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T17:53:59", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T19:00:37", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T22:17:33", - "normal": 7.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T22:17:33", - "normal": 7.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-04T09:52:11", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-04T12:55:58", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-04T12:55:58", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-04T15:12:11", - "normal": 6.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-04T20:09:22", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-05T03:27:19", - "normal": 4.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-05T03:27:19", - "normal": 4.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-05T19:22:47", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-05T19:22:47", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-05T22:39:45", - "normal": 10.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-05T22:39:45", - "normal": 10.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T06:12:37", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T06:12:37", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T12:42:06", - "normal": 8.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T15:32:00", - "expectedNormal": 4.7, - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T19:07:20", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T19:39:58", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-07T00:20:47", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-07T05:30:49", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-07T08:21:15", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-07T22:44:14", - "normal": 8.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-08T06:58:25", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-08T08:16:59", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-08T13:52:10", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-08T19:52:08", - "normal": 5.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-08T19:52:08", - "normal": 5.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T06:26:22", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T06:26:22", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T07:43:04", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T15:08:46", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T15:54:44", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T23:03:47", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T23:38:04", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T23:38:04", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-10T16:02:43", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-10T22:56:35", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-10T22:56:35", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-10T23:35:59", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-11T15:03:25", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-11T15:03:25", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-11T16:13:04", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-11T21:19:03", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-11T21:19:03", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T07:22:58", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T15:16:54", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T15:16:54", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T15:54:25", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T21:11:04", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T21:11:04", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T13:15:55", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T13:18:43", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T13:18:43", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T16:26:19", - "normal": 6.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T16:26:19", - "normal": 6.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T20:33:47", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T20:33:47", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T20:49:06", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T21:24:48", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T23:18:40", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T23:45:17", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T00:25:53", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T01:10:52", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T12:00:00", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T15:36:08", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T16:01:10", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T19:58:59", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T20:51:48", - "normal": 8.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T20:51:48", - "normal": 8.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T21:40:26", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T23:14:13", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T00:33:52", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T00:33:52", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T08:45:17", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T15:49:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T21:53:25", - "normal": 8.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T21:53:25", - "normal": 8.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T22:38:18", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-16T16:47:33", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-16T22:22:47", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-16T23:27:48", - "normal": 14.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-17T15:50:12", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-17T15:52:31", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T14:12:19", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T15:09:54", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T15:27:12", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T15:57:46", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T23:28:05", - "normal": 8.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T23:28:05", - "normal": 8.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T00:10:14", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T00:46:24", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T01:11:02", - "normal": 5.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T14:59:14", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T16:28:00", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T22:00:22", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T23:24:34", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T17:39:33", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T19:27:43", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T20:07:49", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T20:43:12", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T21:54:33", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-21T14:16:42", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-21T20:42:35", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-22T12:14:12", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T07:12:15", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T11:12:32", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T12:36:16", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T12:50:53", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T14:17:09", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-24T10:47:06", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-24T14:20:06", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-24T16:11:40", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-25T00:18:43", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-25T19:12:42", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-25T19:12:42", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-25T20:42:26", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-25T20:42:26", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-26T18:49:01", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-27T18:11:11", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-27T20:47:51", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-28T13:28:57", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-28T13:31:35", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-28T13:43:39", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-28T18:08:08", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-29T03:56:45", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-29T03:56:45", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-29T15:09:37", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-29T15:58:27", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-29T15:58:27", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-30T02:57:09", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-30T16:34:05", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-30T19:17:07", - "expectedNormal": 8, - "normal": 6.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-30T23:28:05", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-31T20:19:12", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-01T16:10:05", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-01T23:01:05", - "normal": 3.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-01T23:01:05", - "normal": 3.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-02T17:16:10", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-02T23:46:20", - "normal": 8.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-03T12:56:37", - "normal": 6.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-03T13:09:30", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-03T16:07:02", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-03T20:10:25", - "duration": 3600000, - "extended": 2.2, - "normal": 12.3, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-03T20:10:25", - "duration": 3600000, - "extended": 2.2, - "normal": 12.3, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T05:00:38", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T05:00:38", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T12:35:17", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T12:35:17", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T15:46:38", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T15:46:38", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T22:01:14", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-05T09:37:58", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-05T13:19:18", - "normal": 2, - "subType": "normal", - }, -} - -var jfBasalStr = `[ - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T22:00:00", - "duration": 1217000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T22:20:17", - "duration": 800000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T22:33:37", - "duration": 5183000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T00:00:00", - "duration": 7992000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T02:13:12", - "duration": 2334000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T05:52:06", - "duration": 6987000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T07:48:33", - "duration": 1140000, - "percent": 0.4, - "rate": 0.62, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T07:48:33", - "duration": 1140000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-11-15T12:49:31Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T07:48:33", - "duration": 1109000, - "expectedDuration": 1140000, - "percent": 0.4, - "rate": 0.62, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T07:48:33", - "duration": 1140000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-11-15T12:49:31Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T08:07:02", - "duration": 2631000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T08:50:53", - "duration": 8779000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:17:12", - "duration": 1800000, - "percent": 0.6, - "rate": 0.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:17:12", - "duration": 1800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-15T16:18:10Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:47:12", - "duration": 592000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:57:04", - "duration": 7200000, - "percent": 0.35, - "rate": 0.5, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:57:04", - "duration": 7200000, - "rate": 1.43, - "scheduleName": "basal 3", - "time": "2017-11-15T16:58:02Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:57:04", - "duration": 176000, - "expectedDuration": 7200000, - "percent": 0.35, - "rate": 0.5, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:57:04", - "duration": 7200000, - "rate": 1.43, - "scheduleName": "basal 3", - "time": "2017-11-15T16:58:02Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T12:00:00", - "duration": 7200000, - "percent": 0.35, - "rate": 0.22, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T12:00:00", - "duration": 7200000, - "rate": 0.63, - "scheduleName": "basal 3", - "time": "2017-11-15T17:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T12:00:00", - "duration": 7024000, - "expectedDuration": 7200000, - "percent": 0.35, - "rate": 0.22, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T12:00:00", - "duration": 7200000, - "rate": 0.63, - "scheduleName": "basal 3", - "time": "2017-11-15T17:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T13:57:04", - "duration": 14576000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T08:30:00", - "duration": 3356000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T09:25:56", - "duration": 7200000, - "percent": 0.5, - "rate": 0.72, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T09:25:56", - "duration": 7200000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2017-11-16T14:26:54Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T11:25:56", - "duration": 2044000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T12:00:00", - "duration": 1425000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T12:23:45", - "duration": 5400000, - "percent": 0.5, - "rate": 0.32, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T12:23:45", - "duration": 5400000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2017-11-16T17:24:43Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T13:53:45", - "duration": 14775000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T00:00:00", - "duration": 2543000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T00:42:23", - "duration": 12600000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T00:42:23", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-17T05:43:21Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T00:42:23", - "duration": 10057000, - "expectedDuration": 12600000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T00:42:23", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-17T05:43:21Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T03:30:00", - "duration": 12600000, - "percent": 0.65, - "rate": 0.84, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T03:30:00", - "duration": 12600000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2017-11-17T08:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T03:30:00", - "duration": 2543000, - "expectedDuration": 12600000, - "percent": 0.65, - "rate": 0.84, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T03:30:00", - "duration": 12600000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2017-11-17T08:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T04:12:23", - "duration": 4657000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T08:30:00", - "duration": 10937000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T11:32:17", - "duration": 10800000, - "percent": 0.6, - "rate": 0.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T11:32:17", - "duration": 10800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-17T16:33:15Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T11:32:17", - "duration": 1663000, - "expectedDuration": 10800000, - "percent": 0.6, - "rate": 0.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T11:32:17", - "duration": 10800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-17T16:33:15Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T12:00:00", - "duration": 7860000, - "percent": 0.6, - "rate": 0.39, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T12:00:00", - "duration": 7860000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-11-17T17:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T12:00:00", - "duration": 6157000, - "expectedDuration": 7860000, - "percent": 0.6, - "rate": 0.39, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T12:00:00", - "duration": 7860000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-11-17T17:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T13:42:37", - "duration": 47000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T13:43:24", - "duration": 10800000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T13:43:24", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-11-17T18:44:22Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T16:43:24", - "duration": 4596000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T18:00:00", - "duration": 2896000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T18:48:16", - "duration": 4862000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T20:09:18", - "duration": 6642000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T00:00:00", - "duration": 10582000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T02:56:22", - "duration": 21600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T02:56:22", - "duration": 21600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-20T07:57:20Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T02:56:22", - "duration": 2018000, - "expectedDuration": 21600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T02:56:22", - "duration": 21600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-20T07:57:20Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T03:30:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T03:30:00", - "duration": 21600000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-11-20T08:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T03:30:00", - "duration": 7200000, - "expectedDuration": 21600000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T03:30:00", - "duration": 21600000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-11-20T08:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T05:30:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T05:30:00", - "duration": 21600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-11-20T10:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T05:30:00", - "duration": 10800000, - "expectedDuration": 21600000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T05:30:00", - "duration": 21600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-11-20T10:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T08:30:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T08:30:00", - "duration": 21600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-20T13:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T08:30:00", - "duration": 1582000, - "expectedDuration": 21600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T08:30:00", - "duration": 21600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-20T13:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T08:56:22", - "duration": 11018000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T12:00:00", - "duration": 7848000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T14:10:48", - "duration": 9000000, - "percent": 1.25, - "rate": 0.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T14:10:48", - "duration": 9000000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-11-20T19:11:46Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T16:40:48", - "duration": 4752000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T18:00:00", - "duration": 4786000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T19:19:46", - "duration": 492000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T19:27:58", - "duration": 9122000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T08:30:00", - "duration": 5770000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:06:10", - "duration": 1860000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:06:10", - "duration": 1860000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-22T15:07:08Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:06:10", - "duration": 1803000, - "expectedDuration": 1860000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:06:10", - "duration": 1860000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-22T15:07:08Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:36:13", - "duration": 13000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:36:26", - "duration": 3600000, - "percent": 1.15, - "rate": 1.66, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:36:26", - "duration": 3600000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2017-11-22T15:37:24Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T11:36:26", - "duration": 1414000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T12:00:00", - "duration": 19357000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T17:22:37", - "duration": 385000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T17:29:02", - "duration": 1858000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T12:00:00", - "duration": 499000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T12:08:19", - "duration": 9000000, - "percent": 0.55, - "rate": 0.35, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T12:08:19", - "duration": 9000000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2017-11-23T17:09:17Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T14:38:19", - "duration": 8117000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T16:53:36", - "duration": 5400000, - "percent": 1.5, - "rate": 0.97, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T16:53:36", - "duration": 5400000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-11-23T21:54:34Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T16:53:36", - "duration": 3984000, - "expectedDuration": 5400000, - "percent": 1.5, - "rate": 0.97, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T16:53:36", - "duration": 5400000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-11-23T21:54:34Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T18:00:00", - "duration": 5400000, - "percent": 1.5, - "rate": 1.72, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T18:00:00", - "duration": 5400000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2017-11-23T23:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T18:00:00", - "duration": 1416000, - "expectedDuration": 5400000, - "percent": 1.5, - "rate": 1.72, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T18:00:00", - "duration": 5400000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2017-11-23T23:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T18:23:36", - "duration": 12984000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T22:00:00", - "duration": 1335000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T22:22:15", - "duration": 7200000, - "percent": 0.7, - "rate": 0.91, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T22:22:15", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-11-24T03:23:13Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T22:22:15", - "duration": 5865000, - "expectedDuration": 7200000, - "percent": 0.7, - "rate": 0.91, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T22:22:15", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-11-24T03:23:13Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T00:00:00", - "duration": 7200000, - "percent": 0.7, - "rate": 1.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T00:00:00", - "duration": 7200000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2017-11-24T05:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T00:00:00", - "duration": 1335000, - "expectedDuration": 7200000, - "percent": 0.7, - "rate": 1.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T00:00:00", - "duration": 7200000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2017-11-24T05:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T00:22:15", - "duration": 5651000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T01:56:26", - "duration": 16200000, - "percent": 0.5, - "rate": 0.72, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T01:56:26", - "duration": 16200000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2017-11-24T06:57:24Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T01:56:26", - "duration": 5614000, - "expectedDuration": 16200000, - "percent": 0.5, - "rate": 0.72, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T01:56:26", - "duration": 16200000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2017-11-24T06:57:24Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:30:00", - "duration": 6360000, - "percent": 0.5, - "rate": 0.65, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:30:00", - "duration": 6360000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-11-24T08:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:30:00", - "duration": 713000, - "expectedDuration": 6360000, - "percent": 0.5, - "rate": 0.65, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:30:00", - "duration": 6360000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-11-24T08:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:41:53", - "duration": 14000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:42:07", - "duration": 480000, - "percent": 0.15000000000000002, - "rate": 0.19, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:42:07", - "duration": 480000, - "rate": 1.27, - "scheduleName": "basal 3", - "time": "2017-11-24T08:43:05Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:42:07", - "duration": 453000, - "expectedDuration": 480000, - "percent": 0.15000000000000002, - "rate": 0.19, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:42:07", - "duration": 480000, - "rate": 1.27, - "scheduleName": "basal 3", - "time": "2017-11-24T08:43:05Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:49:40", - "duration": 21000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:50:01", - "duration": 1260000, - "rate": 0 - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:50:01", - "duration": 1243000, - "expectedDuration": 1260000, - "rate": 0 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T04:10:44", - "duration": 17000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T04:11:01", - "duration": 25200000, - "percent": 0.30000000000000004, - "rate": 0.39, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T04:11:01", - "duration": 25200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-11-24T09:11:59Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T04:11:01", - "duration": 4739000, - "expectedDuration": 25200000, - "percent": 0.30000000000000004, - "rate": 0.39, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T04:11:01", - "duration": 25200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-11-24T09:11:59Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T05:30:00", - "duration": 25200000, - "percent": 0.30000000000000004, - "rate": 0.46, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T05:30:00", - "duration": 25200000, - "rate": 1.53, - "scheduleName": "basal 3", - "time": "2017-11-24T10:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T05:30:00", - "duration": 10800000, - "expectedDuration": 25200000, - "percent": 0.30000000000000004, - "rate": 0.46, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T05:30:00", - "duration": 25200000, - "rate": 1.53, - "scheduleName": "basal 3", - "time": "2017-11-24T10:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T08:30:00", - "duration": 21000000, - "percent": 0.30000000000000004, - "rate": 0.43, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T08:30:00", - "duration": 21000000, - "rate": 1.43, - "scheduleName": "basal 3", - "time": "2017-11-24T13:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T08:30:00", - "duration": 5443000, - "expectedDuration": 21000000, - "percent": 0.30000000000000004, - "rate": 0.43, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T08:30:00", - "duration": 21000000, - "rate": 1.43, - "scheduleName": "basal 3", - "time": "2017-11-24T13:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T10:00:43", - "duration": 7157000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T08:30:00", - "duration": 7831000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T10:40:31", - "duration": 3660000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T10:40:31", - "duration": 3660000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-25T15:41:29Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T10:40:31", - "duration": 3630000, - "expectedDuration": 3660000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T10:40:31", - "duration": 3660000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-25T15:41:29Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T11:41:01", - "duration": 26048000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T18:55:09", - "duration": 11091000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T08:30:00", - "duration": 4143000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T09:39:03", - "duration": 5400000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T09:39:03", - "duration": 5400000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-26T14:40:01Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T11:09:03", - "duration": 3057000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T12:00:00", - "duration": 11173000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T15:06:13", - "duration": 10800000, - "percent": 0.5, - "rate": 0.32, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T15:06:13", - "duration": 10800000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2017-11-27T20:07:11Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T15:06:13", - "duration": 10427000, - "expectedDuration": 10800000, - "percent": 0.5, - "rate": 0.32, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T15:06:13", - "duration": 10800000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2017-11-27T20:07:11Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T18:00:00", - "duration": 10800000, - "percent": 0.5, - "rate": 0.57, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T18:00:00", - "duration": 10800000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2017-11-27T23:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T18:00:00", - "duration": 373000, - "expectedDuration": 10800000, - "percent": 0.5, - "rate": 0.57, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T18:00:00", - "duration": 10800000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2017-11-27T23:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T18:06:13", - "duration": 14027000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T05:30:00", - "duration": 7330000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T07:32:10", - "duration": 8320000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T09:50:50", - "duration": 7750000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T12:00:00", - "duration": 13768000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T15:49:28", - "duration": 1919000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T13:21:27", - "duration": 16713000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T18:00:00", - "duration": 7752000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T20:09:12", - "duration": 4951000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T21:31:43", - "duration": 1697000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T05:30:00", - "duration": 2075000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T06:04:35", - "duration": 5400000, - "percent": 1.4, - "rate": 2.17, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T06:04:35", - "duration": 5400000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-12-01T14:05:33Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T07:34:35", - "duration": 3325000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T08:30:00", - "duration": 6166000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T10:12:46", - "duration": 5400000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T10:12:46", - "duration": 5400000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-01T18:13:44Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T11:42:46", - "duration": 1034000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T22:00:00", - "duration": 4345000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T23:12:25", - "duration": 1767000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T23:41:52", - "duration": 1088000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T05:30:00", - "duration": 7632000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T07:37:12", - "duration": 7359000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T09:39:51", - "duration": 8409000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T08:30:00", - "duration": 7692000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T10:38:12", - "duration": 1864000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T11:09:16", - "duration": 3044000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T18:00:00", - "duration": 11017000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T21:03:37", - "duration": 10800000, - "percent": 1.5, - "rate": 1.72, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T21:03:37", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2017-12-13T05:04:35Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T21:03:37", - "duration": 3383000, - "expectedDuration": 10800000, - "percent": 1.5, - "rate": 1.72, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T21:03:37", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2017-12-13T05:04:35Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T22:00:00", - "duration": 10800000, - "percent": 1.5, - "rate": 1.95, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T22:00:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-13T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T22:00:00", - "duration": 7200000, - "expectedDuration": 10800000, - "percent": 1.5, - "rate": 1.95, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T22:00:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-13T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T00:00:00", - "duration": 10800000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T00:00:00", - "duration": 10800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-13T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T00:00:00", - "duration": 217000, - "expectedDuration": 10800000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T00:00:00", - "duration": 10800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-13T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T00:03:37", - "duration": 12383000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T05:30:00", - "duration": 5676000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T07:04:36", - "duration": 7200000, - "percent": 0.4, - "rate": 0.62, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T07:04:36", - "duration": 7200000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-12-13T15:05:34Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T07:04:36", - "duration": 5124000, - "expectedDuration": 7200000, - "percent": 0.4, - "rate": 0.62, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T07:04:36", - "duration": 7200000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-12-13T15:05:34Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T08:30:00", - "duration": 7200000, - "percent": 0.4, - "rate": 0.58, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T08:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-13T16:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T08:30:00", - "duration": 2076000, - "expectedDuration": 7200000, - "percent": 0.4, - "rate": 0.58, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T08:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-13T16:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T09:04:36", - "duration": 8062000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T11:18:58", - "duration": 3600000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T11:18:58", - "duration": 3600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-13T19:19:56Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T11:18:58", - "duration": 2462000, - "expectedDuration": 3600000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T11:18:58", - "duration": 3600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-13T19:19:56Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T12:00:00", - "duration": 3600000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T12:00:00", - "duration": 3600000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-12-13T20:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T12:00:00", - "duration": 1138000, - "expectedDuration": 3600000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T12:00:00", - "duration": 3600000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-12-13T20:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T12:18:58", - "duration": 20462000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T18:00:00", - "duration": 3789000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T19:03:09", - "duration": 4406000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T20:16:35", - "duration": 6205000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T12:00:00", - "duration": 21479000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T17:57:59", - "duration": 7200000, - "percent": 1.45, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T17:57:59", - "duration": 7200000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-12-16T01:58:57Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T17:57:59", - "duration": 121000, - "expectedDuration": 7200000, - "percent": 1.45, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T17:57:59", - "duration": 7200000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-12-16T01:58:57Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T18:00:00", - "duration": 7200000, - "percent": 1.45, - "rate": 1.66, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T18:00:00", - "duration": 7200000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2017-12-16T02:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T18:00:00", - "duration": 7079000, - "expectedDuration": 7200000, - "percent": 1.45, - "rate": 1.66, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T18:00:00", - "duration": 7200000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2017-12-16T02:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T19:57:59", - "duration": 7321000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T03:30:00", - "duration": 6942000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:25:42", - "duration": 5400000, - "percent": 1.5, - "rate": 1.95, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:25:42", - "duration": 5400000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-16T13:26:40Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:25:42", - "duration": 258000, - "expectedDuration": 5400000, - "percent": 1.5, - "rate": 1.95, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:25:42", - "duration": 5400000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-16T13:26:40Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:30:00", - "duration": 5400000, - "percent": 1.5, - "rate": 2.32, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:30:00", - "duration": 5400000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-12-16T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:30:00", - "duration": 5142000, - "expectedDuration": 5400000, - "percent": 1.5, - "rate": 2.32, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:30:00", - "duration": 5400000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-12-16T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T06:55:42", - "duration": 5658000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T18:00:00", - "duration": 12497000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T21:28:17", - "duration": 2135000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T22:03:52", - "duration": 6968000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T00:00:00", - "duration": 4032000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T01:07:12", - "duration": 7200000, - "percent": 1.75, - "rate": 2.53, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T01:07:12", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-17T09:08:10Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T03:07:12", - "duration": 1368000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T22:00:00", - "duration": 4835000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T23:20:35", - "duration": 5400000, - "percent": 1.5, - "rate": 1.95, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T23:20:35", - "duration": 5400000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-19T07:21:33Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T23:20:35", - "duration": 2365000, - "expectedDuration": 5400000, - "percent": 1.5, - "rate": 1.95, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T23:20:35", - "duration": 5400000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-19T07:21:33Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T00:00:00", - "duration": 5400000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T00:00:00", - "duration": 5400000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-19T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T00:00:00", - "duration": 3035000, - "expectedDuration": 5400000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T00:00:00", - "duration": 5400000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-19T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T00:50:35", - "duration": 9565000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T05:30:00", - "duration": 1701000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T05:58:21", - "duration": 50296000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T19:56:37", - "duration": 7403000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T18:00:00", - "duration": 8649000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T20:24:09", - "duration": 9000000, - "percent": 1.95, - "rate": 2.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T20:24:09", - "duration": 9000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2017-12-23T04:25:07Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T20:24:09", - "duration": 5751000, - "expectedDuration": 9000000, - "percent": 1.95, - "rate": 2.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T20:24:09", - "duration": 9000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2017-12-23T04:25:07Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T22:00:00", - "duration": 9000000, - "percent": 1.95, - "rate": 2.53, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T22:00:00", - "duration": 9000000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-23T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T22:00:00", - "duration": 3249000, - "expectedDuration": 9000000, - "percent": 1.95, - "rate": 2.53, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T22:00:00", - "duration": 9000000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-23T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T22:54:09", - "duration": 3951000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T18:00:00", - "duration": 366000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T18:06:06", - "duration": 613000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T18:16:19", - "duration": 13421000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T03:30:00", - "duration": 5480000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:01:20", - "duration": 12600000, - "percent": 1.6, - "rate": 2.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:01:20", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-25T13:02:18Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:01:20", - "duration": 1720000, - "expectedDuration": 12600000, - "percent": 1.6, - "rate": 2.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:01:20", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-25T13:02:18Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:30:00", - "duration": 12600000, - "percent": 1.6, - "rate": 2.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:30:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-12-25T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:30:00", - "duration": 10800000, - "expectedDuration": 12600000, - "percent": 1.6, - "rate": 2.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:30:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-12-25T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T08:30:00", - "duration": 12600000, - "percent": 1.6, - "rate": 2.32, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-25T16:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T08:30:00", - "duration": 80000, - "expectedDuration": 12600000, - "percent": 1.6, - "rate": 2.32, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-25T16:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T08:31:20", - "duration": 12520000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T05:30:00", - "duration": 3692000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T06:31:32", - "duration": 14400000, - "percent": 1.65, - "rate": 2.55, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T06:31:32", - "duration": 14400000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-12-26T14:32:30Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T06:31:32", - "duration": 7108000, - "expectedDuration": 14400000, - "percent": 1.65, - "rate": 2.55, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T06:31:32", - "duration": 14400000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-12-26T14:32:30Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T08:30:00", - "duration": 14400000, - "percent": 1.65, - "rate": 2.39, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T08:30:00", - "duration": 14400000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-26T16:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T08:30:00", - "duration": 7292000, - "expectedDuration": 14400000, - "percent": 1.65, - "rate": 2.39, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T08:30:00", - "duration": 14400000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-26T16:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T10:31:32", - "duration": 5308000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T18:00:00", - "duration": 9007000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T20:30:07", - "duration": 4826000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T21:50:33", - "duration": 567000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T12:00:00", - "duration": 175000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T12:02:55", - "duration": 203000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T12:06:18", - "duration": 21222000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T22:00:00", - "duration": 5252000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T23:27:32", - "duration": 7200000, - "percent": 1.45, - "rate": 1.88, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T23:27:32", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-31T07:28:30Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T23:27:32", - "duration": 1948000, - "expectedDuration": 7200000, - "percent": 1.45, - "rate": 1.88, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T23:27:32", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-31T07:28:30Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T00:00:00", - "duration": 7200000, - "percent": 1.45, - "rate": 2.1, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T00:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-31T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T00:00:00", - "duration": 5252000, - "expectedDuration": 7200000, - "percent": 1.45, - "rate": 2.1, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T00:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-31T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T01:27:32", - "duration": 7348000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T05:30:00", - "duration": 10163000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T08:19:23", - "duration": 227000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T08:23:10", - "duration": 410000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T08:30:00", - "duration": 1916000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T09:01:56", - "duration": 291000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T09:06:47", - "duration": 10393000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T00:00:00", - "duration": 2058000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T00:34:18", - "duration": 18000000, - "percent": 1.3, - "rate": 1.88, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T00:34:18", - "duration": 18000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-01-05T08:35:16Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T00:34:18", - "duration": 10542000, - "expectedDuration": 18000000, - "percent": 1.3, - "rate": 1.88, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T00:34:18", - "duration": 18000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-01-05T08:35:16Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T03:30:00", - "duration": 18000000, - "percent": 1.3, - "rate": 1.69, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T03:30:00", - "duration": 18000000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-01-05T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T03:30:00", - "duration": 7200000, - "expectedDuration": 18000000, - "percent": 1.3, - "rate": 1.69, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T03:30:00", - "duration": 18000000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-01-05T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T05:30:00", - "duration": 18000000, - "percent": 1.3, - "rate": 2.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T05:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-01-05T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T05:30:00", - "duration": 258000, - "expectedDuration": 18000000, - "percent": 1.3, - "rate": 2.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T05:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-01-05T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T05:34:18", - "duration": 10542000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T00:00:00", - "duration": 5352000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T01:29:12", - "duration": 16200000, - "percent": 1.45, - "rate": 2.1, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T01:29:12", - "duration": 16200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-01-06T09:30:10Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T01:29:12", - "duration": 7248000, - "expectedDuration": 16200000, - "percent": 1.45, - "rate": 2.1, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T01:29:12", - "duration": 16200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-01-06T09:30:10Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T03:30:00", - "duration": 16200000, - "percent": 1.45, - "rate": 1.88, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T03:30:00", - "duration": 16200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-01-06T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T03:30:00", - "duration": 7200000, - "expectedDuration": 16200000, - "percent": 1.45, - "rate": 1.88, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T03:30:00", - "duration": 16200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-01-06T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T05:30:00", - "duration": 16200000, - "percent": 1.45, - "rate": 2.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T05:30:00", - "duration": 16200000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-01-06T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T05:30:00", - "duration": 1752000, - "expectedDuration": 16200000, - "percent": 1.45, - "rate": 2.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T05:30:00", - "duration": 16200000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-01-06T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T05:59:12", - "duration": 9048000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T08:30:00", - "duration": 10301000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T11:21:41", - "duration": 1674000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T11:49:35", - "duration": 625000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T12:00:00", - "duration": 10354000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T14:52:34", - "duration": 729000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T15:04:43", - "duration": 10517000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T05:30:00", - "duration": 6107000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T07:11:47", - "duration": 3600000, - "percent": 0.35, - "rate": 0.54, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T07:11:47", - "duration": 3600000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-01-10T15:12:45Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T08:11:47", - "duration": 1093000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T08:30:00", - "duration": 5259000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T09:57:39", - "duration": 54000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T09:58:33", - "duration": 7287000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T22:00:00", - "duration": 4793000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T23:19:53", - "duration": 5171000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T00:46:04", - "duration": 9836000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T12:00:00", - "duration": 19060000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T17:17:40", - "duration": 298000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T17:22:38", - "duration": 2242000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T18:00:00", - "duration": 762000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T18:12:42", - "duration": 364000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T18:18:46", - "duration": 13274000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T08:30:00", - "duration": 3806000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T09:33:26", - "duration": 32400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T09:33:26", - "duration": 32400000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-01-19T17:34:24Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T09:33:26", - "duration": 8794000, - "expectedDuration": 32400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T09:33:26", - "duration": 32400000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-01-19T17:34:24Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T12:00:00", - "duration": 32400000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T12:00:00", - "duration": 32400000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-01-19T20:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T12:00:00", - "duration": 21600000, - "expectedDuration": 32400000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T12:00:00", - "duration": 32400000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-01-19T20:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T18:00:00", - "duration": 32400000, - "percent": 0.75, - "rate": 0.86, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T18:00:00", - "duration": 32400000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-01-20T02:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T18:00:00", - "duration": 2006000, - "expectedDuration": 32400000, - "percent": 0.75, - "rate": 0.86, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T18:00:00", - "duration": 32400000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-01-20T02:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T18:33:26", - "duration": 12394000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T08:30:00", - "duration": 12207000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T11:53:27", - "duration": 10800000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T11:53:27", - "duration": 10800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-01-20T19:54:25Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T11:53:27", - "duration": 393000, - "expectedDuration": 10800000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T11:53:27", - "duration": 10800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-01-20T19:54:25Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T12:00:00", - "duration": 10800000, - "percent": 0.65, - "rate": 0.42, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T12:00:00", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-01-20T20:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T12:00:00", - "duration": 10407000, - "expectedDuration": 10800000, - "percent": 0.65, - "rate": 0.42, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T12:00:00", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-01-20T20:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T14:53:27", - "duration": 11193000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T00:00:00", - "duration": 4261000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T01:11:01", - "duration": 404000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T01:17:45", - "duration": 7935000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T08:30:00", - "duration": 1757000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T08:59:17", - "duration": 695000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T09:10:52", - "duration": 10148000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T12:00:00", - "duration": 18043000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T17:00:43", - "duration": 2404000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T17:40:47", - "duration": 1153000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T00:00:00", - "duration": 4572000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T01:16:12", - "duration": 303000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T01:21:15", - "duration": 7725000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T08:30:00", - "duration": 1219000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T08:50:19", - "duration": 5400000, - "percent": 1.3, - "rate": 1.88, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T08:50:19", - "duration": 5400000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-01-31T16:51:17Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T10:20:19", - "duration": 5981000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T12:00:00", - "duration": 14758000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T16:05:58", - "duration": 375000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T16:12:13", - "duration": 6467000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T18:00:00", - "duration": 11599000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T21:13:19", - "duration": 711000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T21:25:10", - "duration": 2090000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T18:00:00", - "duration": 10305000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T20:51:45", - "duration": 7200000, - "percent": 0.19999999999999996, - "rate": 0.23, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T20:51:45", - "duration": 7200000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-02-04T04:52:43Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T20:51:45", - "duration": 4095000, - "expectedDuration": 7200000, - "percent": 0.19999999999999996, - "rate": 0.23, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T20:51:45", - "duration": 7200000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-02-04T04:52:43Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T22:00:00", - "duration": 7200000, - "percent": 0.19999999999999996, - "rate": 0.28, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-02-04T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T22:00:00", - "duration": 3105000, - "expectedDuration": 7200000, - "percent": 0.19999999999999996, - "rate": 0.28, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-02-04T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T22:51:45", - "duration": 4095000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T12:00:00", - "duration": 19370000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T17:22:50", - "duration": 3600000, - "percent": 0.7, - "rate": 0.45, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T17:22:50", - "duration": 3600000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-02-06T01:23:48Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T17:22:50", - "duration": 2230000, - "expectedDuration": 3600000, - "percent": 0.7, - "rate": 0.45, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T17:22:50", - "duration": 3600000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-02-06T01:23:48Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T18:00:00", - "duration": 3600000, - "percent": 0.7, - "rate": 0.8, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T18:00:00", - "duration": 3600000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-02-06T02:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T18:00:00", - "duration": 1370000, - "expectedDuration": 3600000, - "percent": 0.7, - "rate": 0.8, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T18:00:00", - "duration": 3600000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-02-06T02:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T18:22:50", - "duration": 13030000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T03:30:00", - "duration": 7580000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T05:36:20", - "duration": 249000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T05:40:29", - "duration": 10171000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T08:30:00", - "duration": 169000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T08:32:49", - "duration": 544000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T08:41:53", - "duration": 11887000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T12:00:00", - "duration": 16275000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T16:31:15", - "duration": 455000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T16:38:50", - "duration": 4870000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T18:00:00", - "duration": 13413000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T21:43:33", - "duration": 246000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T21:47:39", - "duration": 741000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:00:00", - "duration": 643000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:10:43", - "duration": 60000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:10:43", - "duration": 60000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-15T08:11:41Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:10:43", - "duration": 7000, - "expectedDuration": 60000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:10:43", - "duration": 60000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-15T08:11:41Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:10:50", - "duration": 273000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:15:23", - "duration": 28000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:15:51", - "duration": 7200000, - "percent": 1.3, - "rate": 1.95, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:15:51", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-15T08:16:49Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T02:15:51", - "duration": 4449000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T00:00:00", - "duration": 10840000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:00:40", - "duration": 10800000, - "percent": 1.45, - "rate": 2.17, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:00:40", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-16T11:01:38Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:00:40", - "duration": 1760000, - "expectedDuration": 10800000, - "percent": 1.45, - "rate": 2.17, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:00:40", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-16T11:01:38Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:30:00", - "duration": 10800000, - "percent": 1.45, - "rate": 1.95, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:30:00", - "duration": 10800000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-02-16T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:30:00", - "duration": 7200000, - "expectedDuration": 10800000, - "percent": 1.45, - "rate": 1.95, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:30:00", - "duration": 10800000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-02-16T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T05:30:00", - "duration": 10800000, - "percent": 1.45, - "rate": 2.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T05:30:00", - "duration": 10800000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-02-16T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T05:30:00", - "duration": 1840000, - "expectedDuration": 10800000, - "percent": 1.45, - "rate": 2.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T05:30:00", - "duration": 10800000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-02-16T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T06:00:40", - "duration": 8960000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T05:30:00", - "duration": 9662000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T08:11:02", - "duration": 6831000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T10:04:53", - "duration": 973000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T10:21:06", - "duration": 97000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T10:22:43", - "duration": 5837000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T12:00:00", - "duration": 4664000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T13:17:44", - "duration": 7380000, - "percent": 1.5, - "rate": 0.97, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T13:17:44", - "duration": 7380000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-02-18T21:18:42Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T13:17:44", - "duration": 7325000, - "expectedDuration": 7380000, - "percent": 1.5, - "rate": 0.97, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T13:17:44", - "duration": 7380000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-02-18T21:18:42Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T15:19:49", - "duration": 9611000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T22:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T22:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T22:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T05:30:00", - "duration": 7957000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T07:42:37", - "duration": 35000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T07:43:12", - "duration": 2808000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T08:30:00", - "duration": 8781000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T10:56:21", - "duration": 254000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T11:00:35", - "duration": 3565000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T00:00:00", - "duration": 4542000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T01:15:42", - "duration": 10800000, - "percent": 0.7, - "rate": 1.05, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T01:15:42", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-22T09:16:40Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T01:15:42", - "duration": 8058000, - "expectedDuration": 10800000, - "percent": 0.7, - "rate": 1.05, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T01:15:42", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-22T09:16:40Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T03:30:00", - "duration": 10800000, - "percent": 0.7, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T03:30:00", - "duration": 10800000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-02-22T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T03:30:00", - "duration": 2742000, - "expectedDuration": 10800000, - "percent": 0.7, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T03:30:00", - "duration": 10800000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-02-22T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T04:15:42", - "duration": 4458000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T18:00:00", - "duration": 366000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T18:06:06", - "duration": 21600000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T18:06:06", - "duration": 21600000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-02-23T02:07:04Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T18:06:06", - "duration": 14034000, - "expectedDuration": 21600000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T18:06:06", - "duration": 21600000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-02-23T02:07:04Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T22:00:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T22:00:00", - "duration": 21600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-02-23T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T22:00:00", - "duration": 7200000, - "expectedDuration": 21600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T22:00:00", - "duration": 21600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-02-23T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T00:00:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T00:00:00", - "duration": 21600000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-23T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T00:00:00", - "duration": 366000, - "expectedDuration": 21600000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T00:00:00", - "duration": 21600000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-23T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T00:06:06", - "duration": 9204000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T02:39:30", - "duration": 18000000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T02:39:30", - "duration": 18000000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-23T10:40:28Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T02:39:30", - "duration": 3030000, - "expectedDuration": 18000000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T02:39:30", - "duration": 18000000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-23T10:40:28Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T03:30:00", - "duration": 18000000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T03:30:00", - "duration": 18000000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-02-23T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T03:30:00", - "duration": 7200000, - "expectedDuration": 18000000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T03:30:00", - "duration": 18000000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-02-23T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T05:30:00", - "duration": 18000000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T05:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-02-23T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T05:30:00", - "duration": 7770000, - "expectedDuration": 18000000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T05:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-02-23T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T07:39:30", - "duration": 3030000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T08:30:00", - "duration": 8164000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T10:46:04", - "duration": 18000000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T10:46:04", - "duration": 18000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-02-23T18:47:02Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T10:46:04", - "duration": 4436000, - "expectedDuration": 18000000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T10:46:04", - "duration": 18000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-02-23T18:47:02Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T12:00:00", - "duration": 18000000, - "percent": 0.65, - "rate": 0.42, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T12:00:00", - "duration": 18000000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-02-23T20:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T12:00:00", - "duration": 13564000, - "expectedDuration": 18000000, - "percent": 0.65, - "rate": 0.42, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T12:00:00", - "duration": 18000000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-02-23T20:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T15:46:04", - "duration": 8036000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T12:00:00", - "duration": 21410000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T17:56:50", - "duration": 2163000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T18:32:53", - "duration": 12427000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T22:00:00", - "duration": 5415000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T23:30:15", - "duration": 7200000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T23:30:15", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-02-26T07:31:13Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T23:30:15", - "duration": 1785000, - "expectedDuration": 7200000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T23:30:15", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-02-26T07:31:13Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T00:00:00", - "duration": 7200000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T00:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-26T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T00:00:00", - "duration": 5415000, - "expectedDuration": 7200000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T00:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-26T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T01:30:15", - "duration": 7185000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T08:30:00", - "duration": 345000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T08:35:45", - "duration": 5400000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T08:35:45", - "duration": 5400000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-02-27T16:36:43Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T10:05:45", - "duration": 6855000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T18:00:00", - "duration": 9705000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T20:41:45", - "duration": 7200000, - "percent": 1.3, - "rate": 1.49, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T20:41:45", - "duration": 7200000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-02-28T04:42:43Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T20:41:45", - "duration": 4695000, - "expectedDuration": 7200000, - "percent": 1.3, - "rate": 1.49, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T20:41:45", - "duration": 7200000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-02-28T04:42:43Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T22:00:00", - "duration": 7200000, - "percent": 1.3, - "rate": 1.88, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-02-28T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T22:00:00", - "duration": 2505000, - "expectedDuration": 7200000, - "percent": 1.3, - "rate": 1.88, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-02-28T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T22:41:45", - "duration": 4695000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T00:00:00", - "duration": 5211000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T01:26:51", - "duration": 199000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T01:30:10", - "duration": 147000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T01:32:37", - "duration": 12600000, - "percent": 0.75, - "rate": 1.12, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T01:32:37", - "duration": 12600000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-02-28T09:33:35Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T01:32:37", - "duration": 7043000, - "expectedDuration": 12600000, - "percent": 0.75, - "rate": 1.12, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T01:32:37", - "duration": 12600000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-02-28T09:33:35Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T03:30:00", - "duration": 12600000, - "percent": 0.75, - "rate": 1.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T03:30:00", - "duration": 12600000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-02-28T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T03:30:00", - "duration": 5557000, - "expectedDuration": 12600000, - "percent": 0.75, - "rate": 1.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T03:30:00", - "duration": 12600000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-02-28T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T05:02:37", - "duration": 1643000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T12:00:00", - "duration": 91000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T12:01:31", - "duration": 7200000, - "percent": 1.35, - "rate": 0.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T12:01:31", - "duration": 7200000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-03-02T20:02:29Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T14:01:31", - "duration": 14309000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T00:00:00", - "duration": 8771000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T02:26:11", - "duration": 272000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T02:30:43", - "duration": 3557000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T08:30:00", - "duration": 5906000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T10:08:26", - "duration": 2274000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T10:46:20", - "duration": 4420000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T18:00:00", - "duration": 2434000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T18:40:34", - "duration": 3332000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T19:36:06", - "duration": 8634000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T22:00:00", - "duration": 7042000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T23:57:22", - "duration": 114000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T23:59:16", - "duration": 44000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T08:30:00", - "duration": 135000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T08:32:15", - "duration": 360000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T09:38:15", - "duration": 8505000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T00:00:00", - "duration": 5721000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T01:35:21", - "duration": 660000, - "percent": 0.6, - "rate": 0.9, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T01:35:21", - "duration": 660000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-03-14T08:36:19Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T01:35:21", - "duration": 638000, - "expectedDuration": 660000, - "percent": 0.6, - "rate": 0.9, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T01:35:21", - "duration": 660000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-03-14T08:36:19Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T01:45:59", - "duration": 6241000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T18:00:00", - "duration": 12763000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T21:32:43", - "duration": 200000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T21:36:03", - "duration": 1437000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T00:00:00", - "duration": 7717000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T02:08:37", - "duration": 9000000, - "percent": 1.2, - "rate": 1.8, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T02:08:37", - "duration": 9000000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-03-16T09:09:35Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T02:08:37", - "duration": 4883000, - "expectedDuration": 9000000, - "percent": 1.2, - "rate": 1.8, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T02:08:37", - "duration": 9000000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-03-16T09:09:35Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T03:30:00", - "duration": 9000000, - "percent": 1.2, - "rate": 1.62, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T03:30:00", - "duration": 9000000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-03-16T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T03:30:00", - "duration": 4117000, - "expectedDuration": 9000000, - "percent": 1.2, - "rate": 1.62, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T03:30:00", - "duration": 9000000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-03-16T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T04:38:37", - "duration": 3083000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T00:00:00", - "duration": 1387000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T00:23:07", - "duration": 5575000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T01:56:02", - "duration": 5638000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T00:00:00", - "duration": 5074000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T01:24:34", - "duration": 3600000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T01:24:34", - "duration": 3600000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-03-20T08:25:32Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T02:24:34", - "duration": 3926000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T12:00:00", - "duration": 14636000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T16:03:56", - "duration": 156000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T16:06:32", - "duration": 6808000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T12:00:00", - "duration": 261000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T12:04:21", - "duration": 241000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T12:08:22", - "duration": 21098000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T08:30:00", - "duration": 5750000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T10:05:50", - "duration": 188000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T10:08:58", - "duration": 6662000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T12:00:00", - "duration": 17191000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T16:46:31", - "duration": 4727000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T18:05:18", - "duration": 14082000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T18:00:00", - "duration": 2581000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T18:43:01", - "duration": 67000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T21:44:08", - "duration": 952000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T18:00:00", - "duration": 9738000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T20:42:18", - "duration": 1004000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T20:59:02", - "duration": 3658000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T00:00:00", - "duration": 12403000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:26:43", - "duration": 7200000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:26:43", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-03-30T07:27:41Z", - "timezoneOffset": -180, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:26:43", - "duration": 197000, - "expectedDuration": 7200000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:26:43", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-03-30T07:27:41Z", - "timezoneOffset": -180, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:30:00", - "duration": 7200000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-03-30T07:30:58Z", - "timezoneOffset": -180, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:30:00", - "duration": 7003000, - "expectedDuration": 7200000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-03-30T07:30:58Z", - "timezoneOffset": -180, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T05:26:43", - "duration": 197000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T18:00:00", - "duration": 3804000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T19:03:24", - "duration": 476000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T19:11:20", - "duration": 10120000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T08:30:00", - "duration": 3078000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T09:21:18", - "duration": 5400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T09:21:18", - "duration": 5400000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-04-03T13:22:16Z", - "timezoneOffset": -180, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T10:51:18", - "duration": 4122000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T18:00:00", - "duration": 8562000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T20:22:42", - "duration": 87000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T17:24:09", - "duration": 2151000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T18:00:00", - "duration": 10423000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T20:53:43", - "duration": 2326000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T21:32:29", - "duration": 1651000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T08:30:00", - "duration": 11164000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T11:36:04", - "duration": 7381000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T13:39:05", - "duration": 15655000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T18:00:00", - "duration": 6679000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T19:51:19", - "duration": 1653000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T20:18:52", - "duration": 6068000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T08:30:00", - "duration": 6131000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T10:12:11", - "duration": 1800000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T10:12:11", - "duration": 1800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-04-10T17:13:09Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T10:42:11", - "duration": 4669000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T12:00:00", - "duration": 243000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T12:04:03", - "duration": 36000000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T12:04:03", - "duration": 36000000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-04-11T19:05:01Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T12:04:03", - "duration": 21357000, - "expectedDuration": 36000000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T12:04:03", - "duration": 36000000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-04-11T19:05:01Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T18:00:00", - "duration": 36000000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T18:00:00", - "duration": 36000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-04-12T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T18:00:00", - "duration": 14400000, - "expectedDuration": 36000000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T18:00:00", - "duration": 36000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-04-12T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T22:00:00", - "duration": 36000000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T22:00:00", - "duration": 36000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-04-12T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T22:00:00", - "duration": 242000, - "expectedDuration": 36000000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T22:00:00", - "duration": 36000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-04-12T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T22:04:02", - "duration": 6958000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T08:30:00", - "duration": 321000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T08:35:21", - "duration": 28800000, - "percent": 0.7, - "rate": 1.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T08:35:21", - "duration": 28800000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-04-12T15:36:19Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T08:35:21", - "duration": 12279000, - "expectedDuration": 28800000, - "percent": 0.7, - "rate": 1.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T08:35:21", - "duration": 28800000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-04-12T15:36:19Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T12:00:00", - "duration": 28200000, - "percent": 0.7, - "rate": 0.45, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T12:00:00", - "duration": 28200000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-04-12T19:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T12:00:00", - "duration": 15906000, - "expectedDuration": 28200000, - "percent": 0.7, - "rate": 0.45, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T12:00:00", - "duration": 28200000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-04-12T19:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T16:25:06", - "duration": 17000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T16:25:23", - "duration": 12600000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T16:25:23", - "duration": 12600000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-04-12T23:26:21Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T16:25:23", - "duration": 5677000, - "expectedDuration": 12600000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T16:25:23", - "duration": 12600000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-04-12T23:26:21Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T18:00:00", - "duration": 12600000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T18:00:00", - "duration": 12600000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-04-13T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T18:00:00", - "duration": 6923000, - "expectedDuration": 12600000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T18:00:00", - "duration": 12600000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-04-13T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T19:55:23", - "duration": 7477000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T22:00:00", - "duration": 5512000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T23:31:52", - "duration": 351000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T23:37:43", - "duration": 562000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T23:47:05", - "duration": 36000000, - "percent": 0.6, - "rate": 0.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T23:47:05", - "duration": 36000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-04-13T06:48:03Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T23:47:05", - "duration": 775000, - "expectedDuration": 36000000, - "percent": 0.6, - "rate": 0.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T23:47:05", - "duration": 36000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-04-13T06:48:03Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:00:00", - "duration": 840000, - "percent": 0.6, - "rate": 0.9, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:00:00", - "duration": 840000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-04-13T07:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:00:00", - "duration": 62000, - "expectedDuration": 840000, - "percent": 0.6, - "rate": 0.9, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:00:00", - "duration": 840000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-04-13T07:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:01:02", - "duration": 13000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:01:15", - "duration": 10380000, - "percent": 0.5, - "rate": 0.75, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:01:15", - "duration": 10380000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-04-13T07:02:13Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:01:15", - "duration": 10367000, - "expectedDuration": 10380000, - "percent": 0.5, - "rate": 0.75, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:01:15", - "duration": 10380000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-04-13T07:02:13Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T02:54:02", - "duration": 17000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T02:54:19", - "duration": 27000000, - "percent": 0.35, - "rate": 0.52, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T02:54:19", - "duration": 27000000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-04-13T09:55:17Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T02:54:19", - "duration": 2141000, - "expectedDuration": 27000000, - "percent": 0.35, - "rate": 0.52, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T02:54:19", - "duration": 27000000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-04-13T09:55:17Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T03:30:00", - "duration": 27000000, - "percent": 0.35, - "rate": 0.47, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T03:30:00", - "duration": 27000000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-04-13T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T03:30:00", - "duration": 7200000, - "expectedDuration": 27000000, - "percent": 0.35, - "rate": 0.47, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T03:30:00", - "duration": 27000000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-04-13T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T05:30:00", - "duration": 14700000, - "percent": 0.35, - "rate": 0.54, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T05:30:00", - "duration": 14700000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-04-13T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T05:30:00", - "duration": 5354000, - "expectedDuration": 14700000, - "percent": 0.35, - "rate": 0.54, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T05:30:00", - "duration": 14700000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-04-13T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T06:59:14", - "duration": 5446000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T08:30:00", - "duration": 1684000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T08:58:04", - "duration": 3600000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T08:58:04", - "duration": 3600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-04-13T15:59:02Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T09:58:04", - "duration": 211000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T10:01:35", - "duration": 3600000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T10:01:35", - "duration": 3600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-04-13T17:02:33Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T11:01:35", - "duration": 3505000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T12:00:00", - "duration": 1514000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T12:25:14", - "duration": 12840000, - "percent": 0.55, - "rate": 0.35, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T12:25:14", - "duration": 12840000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-04-13T19:26:12Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T12:25:14", - "duration": 12810000, - "expectedDuration": 12840000, - "percent": 0.55, - "rate": 0.35, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T12:25:14", - "duration": 12840000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-04-13T19:26:12Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T15:58:44", - "duration": 8000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T15:58:52", - "duration": 5400000, - "percent": 1.25, - "rate": 0.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T15:58:52", - "duration": 5400000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-04-13T22:59:50Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T17:28:52", - "duration": 1868000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T18:00:00", - "duration": 4291000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T19:11:31", - "duration": 60000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T19:11:31", - "duration": 60000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-04-14T02:12:29Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T19:11:31", - "duration": 48000, - "expectedDuration": 60000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T19:11:31", - "duration": 60000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-04-14T02:12:29Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T19:12:19", - "duration": 10061000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T00:00:00", - "duration": 2499000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T00:41:39", - "duration": 7200000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T00:41:39", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-04-14T07:42:37Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T02:41:39", - "duration": 2901000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T05:30:00", - "duration": 10759000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T08:29:19", - "duration": 4125000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T09:38:04", - "duration": 8516000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T12:00:00", - "duration": 4493000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T13:14:53", - "duration": 3600000, - "percent": 0.9, - "rate": 0.58, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T13:14:53", - "duration": 3600000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-04-14T20:15:51Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T14:14:53", - "duration": 13507000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T05:30:00", - "duration": 8560000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T07:52:40", - "duration": 8961000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T10:22:01", - "duration": 5879000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T22:00:00", - "duration": 6208000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T23:43:28", - "duration": 7200000, - "percent": 1.1, - "rate": 1.59, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T23:43:28", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-04-18T06:44:26Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T23:43:28", - "duration": 992000, - "expectedDuration": 7200000, - "percent": 1.1, - "rate": 1.59, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T23:43:28", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-04-18T06:44:26Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T00:00:00", - "duration": 7200000, - "percent": 1.1, - "rate": 1.65, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T00:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-04-18T07:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T00:00:00", - "duration": 6208000, - "expectedDuration": 7200000, - "percent": 1.1, - "rate": 1.65, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T00:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-04-18T07:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T01:43:28", - "duration": 6392000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T12:00:00", - "duration": 11187000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T15:06:27", - "duration": 3600000, - "percent": 0.7, - "rate": 0.45, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T15:06:27", - "duration": 3600000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-04-18T22:07:25Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T16:06:27", - "duration": 6813000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T08:30:00", - "duration": 7374000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T10:32:54", - "duration": 790000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T10:46:04", - "duration": 4436000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T05:30:00", - "duration": 10425000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T08:23:45", - "duration": 375000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T12:00:00", - "duration": 10788000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T14:59:48", - "duration": 3678000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T16:01:06", - "duration": 7134000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T12:00:00", - "duration": 9679000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T14:41:19", - "duration": 10800000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T14:41:19", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-04-22T21:42:17Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T17:41:19", - "duration": 1121000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T22:00:00", - "duration": 4227000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T23:10:27", - "duration": 586000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T23:20:13", - "duration": 2387000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T18:00:00", - "duration": 13412000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T21:43:32", - "duration": 200000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T21:46:52", - "duration": 788000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T00:00:00", - "duration": 3746000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:02:26", - "duration": 180000, - "percent": 0.7, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:02:26", - "duration": 180000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-04-26T08:03:24Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:02:26", - "duration": 128000, - "expectedDuration": 180000, - "percent": 0.7, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:02:26", - "duration": 180000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-04-26T08:03:24Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:04:34", - "duration": 11000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:04:45", - "duration": 18000000, - "percent": 0.85, - "rate": 1.31, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:04:45", - "duration": 18000000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-04-26T08:05:43Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:04:45", - "duration": 8715000, - "expectedDuration": 18000000, - "percent": 0.85, - "rate": 1.31, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:04:45", - "duration": 18000000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-04-26T08:05:43Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T03:30:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.19, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T03:30:00", - "duration": 18000000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-04-26T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T03:30:00", - "duration": 7200000, - "expectedDuration": 18000000, - "percent": 0.85, - "rate": 1.19, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T03:30:00", - "duration": 18000000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-04-26T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T05:30:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.36, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T05:30:00", - "duration": 18000000, - "rate": 1.6, - "scheduleName": "basal 3", - "time": "2018-04-26T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T05:30:00", - "duration": 2085000, - "expectedDuration": 18000000, - "percent": 0.85, - "rate": 1.36, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T05:30:00", - "duration": 18000000, - "rate": 1.6, - "scheduleName": "basal 3", - "time": "2018-04-26T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T06:04:45", - "duration": 8715000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T00:00:00", - "duration": 10498000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T02:54:58", - "duration": 21600000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T02:54:58", - "duration": 21600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-04-27T09:55:56Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T02:54:58", - "duration": 2102000, - "expectedDuration": 21600000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T02:54:58", - "duration": 21600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-04-27T09:55:56Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T03:30:00", - "duration": 21600000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T03:30:00", - "duration": 21600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-04-27T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T03:30:00", - "duration": 7200000, - "expectedDuration": 21600000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T03:30:00", - "duration": 21600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-04-27T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T05:30:00", - "duration": 21600000, - "percent": 0.75, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T05:30:00", - "duration": 21600000, - "rate": 1.6, - "scheduleName": "basal 3", - "time": "2018-04-27T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T05:30:00", - "duration": 10800000, - "expectedDuration": 21600000, - "percent": 0.75, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T05:30:00", - "duration": 21600000, - "rate": 1.6, - "scheduleName": "basal 3", - "time": "2018-04-27T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T08:30:00", - "duration": 21600000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T08:30:00", - "duration": 21600000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-04-27T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T08:30:00", - "duration": 1498000, - "expectedDuration": 21600000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T08:30:00", - "duration": 21600000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-04-27T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T08:54:58", - "duration": 11102000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T22:00:00", - "duration": 4513000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T23:15:13", - "duration": 147000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T23:17:40", - "duration": 2540000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T00:00:00", - "duration": 635000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T00:10:35", - "duration": 315000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T00:15:50", - "duration": 11650000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T18:00:00", - "duration": 1631000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T18:27:11", - "duration": 3420000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T18:27:11", - "duration": 3420000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-03T01:28:09Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T18:27:11", - "duration": 3419000, - "expectedDuration": 3420000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T18:27:11", - "duration": 3420000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-03T01:28:09Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T19:24:10", - "duration": 9350000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T05:30:00", - "duration": 3903000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T06:35:03", - "duration": 7200000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T06:35:03", - "duration": 7200000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-05-03T13:36:01Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T06:35:03", - "duration": 6897000, - "expectedDuration": 7200000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T06:35:03", - "duration": 7200000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-05-03T13:36:01Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T08:30:00", - "duration": 7200000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T08:30:00", - "duration": 7200000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-03T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T08:30:00", - "duration": 303000, - "expectedDuration": 7200000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T08:30:00", - "duration": 7200000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-03T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T08:35:03", - "duration": 2092000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T09:09:55", - "duration": 43200000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T09:09:55", - "duration": 43200000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-03T16:10:53Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T09:09:55", - "duration": 10205000, - "expectedDuration": 43200000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T09:09:55", - "duration": 43200000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-03T16:10:53Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T12:00:00", - "duration": 16200000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T12:00:00", - "duration": 16200000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-05-03T19:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T12:00:00", - "duration": 5994000, - "expectedDuration": 16200000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T12:00:00", - "duration": 16200000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-05-03T19:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T13:39:54", - "duration": 221000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T13:43:35", - "duration": 10550000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T16:39:25", - "duration": 21498000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T22:37:43", - "duration": 4937000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T00:00:00", - "duration": 5097000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T01:24:57", - "duration": 30600000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T01:24:57", - "duration": 30600000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-05-04T08:25:55Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T01:24:57", - "duration": 7503000, - "expectedDuration": 30600000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T01:24:57", - "duration": 30600000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-05-04T08:25:55Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T03:30:00", - "duration": 30600000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T03:30:00", - "duration": 30600000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-05-04T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T03:30:00", - "duration": 7200000, - "expectedDuration": 30600000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T03:30:00", - "duration": 30600000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-05-04T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T05:30:00", - "duration": 30600000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T05:30:00", - "duration": 30600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-05-04T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T05:30:00", - "duration": 10800000, - "expectedDuration": 30600000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T05:30:00", - "duration": 30600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-05-04T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T08:30:00", - "duration": 30600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T08:30:00", - "duration": 30600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-05-04T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T08:30:00", - "duration": 5097000, - "expectedDuration": 30600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T08:30:00", - "duration": 30600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-05-04T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T09:54:57", - "duration": 4178000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T11:04:35", - "duration": 41400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T11:04:35", - "duration": 41400000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-04T18:05:33Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T11:04:35", - "duration": 3325000, - "expectedDuration": 41400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T11:04:35", - "duration": 41400000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-04T18:05:33Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T12:00:00", - "duration": 41400000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T12:00:00", - "duration": 41400000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-05-04T19:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T12:00:00", - "duration": 21600000, - "expectedDuration": 41400000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T12:00:00", - "duration": 41400000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-05-04T19:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T18:00:00", - "duration": 41400000, - "percent": 0.75, - "rate": 0.86, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T18:00:00", - "duration": 41400000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-05T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T18:00:00", - "duration": 14400000, - "expectedDuration": 41400000, - "percent": 0.75, - "rate": 0.86, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T18:00:00", - "duration": 41400000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-05T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T22:00:00", - "duration": 41400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T22:00:00", - "duration": 41400000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-05T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T22:00:00", - "duration": 2075000, - "expectedDuration": 41400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T22:00:00", - "duration": 41400000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-05T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T22:34:35", - "duration": 5125000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T00:00:00", - "duration": 4232000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T01:10:32", - "duration": 28800000, - "percent": 0.75, - "rate": 1.12, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T01:10:32", - "duration": 28800000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-05-05T08:11:30Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T01:10:32", - "duration": 8368000, - "expectedDuration": 28800000, - "percent": 0.75, - "rate": 1.12, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T01:10:32", - "duration": 28800000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-05-05T08:11:30Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T03:30:00", - "duration": 28800000, - "percent": 0.75, - "rate": 1.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T03:30:00", - "duration": 28800000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-05-05T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T03:30:00", - "duration": 7200000, - "expectedDuration": 28800000, - "percent": 0.75, - "rate": 1.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T03:30:00", - "duration": 28800000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-05-05T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T05:30:00", - "duration": 28800000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T05:30:00", - "duration": 28800000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-05-05T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T05:30:00", - "duration": 10800000, - "expectedDuration": 28800000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T05:30:00", - "duration": 28800000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-05-05T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T08:30:00", - "duration": 28800000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T08:30:00", - "duration": 28800000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-05T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T08:30:00", - "duration": 2432000, - "expectedDuration": 28800000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T08:30:00", - "duration": 28800000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-05T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T09:10:32", - "duration": 10168000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T05:30:00", - "duration": 10250000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:20:50", - "duration": 28800000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:20:50", - "duration": 28800000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-05-06T15:21:48Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:20:50", - "duration": 550000, - "expectedDuration": 28800000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:20:50", - "duration": 28800000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-05-06T15:21:48Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:30:00", - "duration": 28800000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:30:00", - "duration": 28800000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-06T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:30:00", - "duration": 12600000, - "expectedDuration": 28800000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:30:00", - "duration": 28800000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-06T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T12:00:00", - "duration": 28800000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T12:00:00", - "duration": 28800000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-05-06T19:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T12:00:00", - "duration": 15650000, - "expectedDuration": 28800000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T12:00:00", - "duration": 28800000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-05-06T19:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T16:20:50", - "duration": 5950000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T18:00:00", - "duration": 9910000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T20:45:10", - "duration": 257000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T20:49:27", - "duration": 4233000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T03:30:00", - "duration": 4311000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T04:41:51", - "duration": 18428000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T09:48:59", - "duration": 7861000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T18:00:00", - "duration": 11857000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T21:17:37", - "duration": 10800000, - "percent": 1.15, - "rate": 1.32, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T21:17:37", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-11T04:18:35Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T21:17:37", - "duration": 2543000, - "expectedDuration": 10800000, - "percent": 1.15, - "rate": 1.32, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T21:17:37", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-11T04:18:35Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T22:00:00", - "duration": 5460000, - "percent": 1.15, - "rate": 1.66, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T22:00:00", - "duration": 5460000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-11T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T22:00:00", - "duration": 2891000, - "expectedDuration": 5460000, - "percent": 1.15, - "rate": 1.66, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T22:00:00", - "duration": 5460000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-11T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T22:48:11", - "duration": 2421000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T23:28:32", - "duration": 3600000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T23:28:32", - "duration": 3600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-05-11T06:29:30Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T23:28:32", - "duration": 1888000, - "expectedDuration": 3600000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T23:28:32", - "duration": 3600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-05-11T06:29:30Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T00:00:00", - "duration": 3600000, - "percent": 1.25, - "rate": 1.93, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T00:00:00", - "duration": 3600000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-05-11T07:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T00:00:00", - "duration": 1712000, - "expectedDuration": 3600000, - "percent": 1.25, - "rate": 1.93, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T00:00:00", - "duration": 3600000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-05-11T07:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T00:28:32", - "duration": 10888000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T12:00:00", - "duration": 21052000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T17:50:52", - "duration": 10800000, - "percent": 1.25, - "rate": 0.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T17:50:52", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-05-13T00:51:50Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T17:50:52", - "duration": 548000, - "expectedDuration": 10800000, - "percent": 1.25, - "rate": 0.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T17:50:52", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-05-13T00:51:50Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T18:00:00", - "duration": 10800000, - "percent": 1.25, - "rate": 1.43, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T18:00:00", - "duration": 10800000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-05-13T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T18:00:00", - "duration": 10252000, - "expectedDuration": 10800000, - "percent": 1.25, - "rate": 1.43, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T18:00:00", - "duration": 10800000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-05-13T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T20:50:52", - "duration": 4148000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T05:30:00", - "duration": 1821000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T06:00:21", - "duration": 217000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T06:03:58", - "duration": 8762000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T18:00:00", - "duration": 2689000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T18:44:49", - "duration": 3986000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T19:51:15", - "duration": 7725000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T18:00:00", - "duration": 8609000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T20:23:29", - "duration": 9000000, - "percent": 1.5, - "rate": 1.72, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T20:23:29", - "duration": 9000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-16T03:24:27Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T20:23:29", - "duration": 5791000, - "expectedDuration": 9000000, - "percent": 1.5, - "rate": 1.72, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T20:23:29", - "duration": 9000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-16T03:24:27Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T22:00:00", - "duration": 7140000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T22:00:00", - "duration": 7140000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-05-16T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T22:00:00", - "duration": 1292000, - "expectedDuration": 7140000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T22:00:00", - "duration": 7140000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-05-16T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T22:21:32", - "duration": 5908000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T12:00:00", - "duration": 16133000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T16:28:53", - "duration": 113000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T16:30:46", - "duration": 5354000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T12:00:00", - "duration": 19563000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T17:26:03", - "duration": 368000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T17:32:11", - "duration": 1669000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T22:00:00", - "duration": 1859000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T22:30:59", - "duration": 3600000, - "percent": 1.95, - "rate": 2.82, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T22:30:59", - "duration": 3600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-05-23T05:31:57Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T23:30:59", - "duration": 1741000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T08:30:00", - "duration": 8897000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T10:58:17", - "duration": 1755000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T11:27:32", - "duration": 1948000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T12:00:00", - "duration": 19655000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T17:27:35", - "duration": 375000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T17:33:50", - "duration": 1570000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T18:00:00", - "duration": 13374000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T21:42:54", - "duration": 10800000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T21:42:54", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-24T04:43:52Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T21:42:54", - "duration": 1026000, - "expectedDuration": 10800000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T21:42:54", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-24T04:43:52Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T22:00:00", - "duration": 10800000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T22:00:00", - "duration": 10800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-05-24T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T22:00:00", - "duration": 7200000, - "expectedDuration": 10800000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T22:00:00", - "duration": 10800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-05-24T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T00:00:00", - "duration": 10800000, - "percent": 1.4, - "rate": 2.1, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T00:00:00", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-05-24T07:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T00:00:00", - "duration": 2574000, - "expectedDuration": 10800000, - "percent": 1.4, - "rate": 2.1, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T00:00:00", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-05-24T07:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T00:42:54", - "duration": 10026000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T08:30:00", - "duration": 11426000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T11:40:26", - "duration": 7949000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T13:52:55", - "duration": 14825000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T08:30:00", - "duration": 2522000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T09:12:02", - "duration": 14514000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T13:13:56", - "duration": 17164000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T18:00:00", - "duration": 14339000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T21:58:59", - "duration": 1800000, - "percent": 0.09999999999999998, - "rate": 0.11, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T21:58:59", - "duration": 1800000, - "rate": 1.1, - "scheduleName": "basal 3", - "time": "2018-05-30T04:59:57Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T21:58:59", - "duration": 61000, - "expectedDuration": 1800000, - "percent": 0.09999999999999998, - "rate": 0.11, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T21:58:59", - "duration": 1800000, - "rate": 1.1, - "scheduleName": "basal 3", - "time": "2018-05-30T04:59:57Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T22:00:00", - "duration": 1800000, - "percent": 0.09999999999999998, - "rate": 0.14, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T22:00:00", - "duration": 1800000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-05-30T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T22:00:00", - "duration": 1739000, - "expectedDuration": 1800000, - "percent": 0.09999999999999998, - "rate": 0.14, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T22:00:00", - "duration": 1800000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-05-30T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T22:28:59", - "duration": 5461000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T12:00:00", - "duration": 20380000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T17:39:40", - "duration": 3600000, - "percent": 0.65, - "rate": 0.42, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T17:39:40", - "duration": 3600000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-05-31T00:40:38Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T17:39:40", - "duration": 1220000, - "expectedDuration": 3600000, - "percent": 0.65, - "rate": 0.42, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T17:39:40", - "duration": 3600000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-05-31T00:40:38Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T18:00:00", - "duration": 3600000, - "percent": 0.65, - "rate": 0.74, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T18:00:00", - "duration": 3600000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-05-31T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T18:00:00", - "duration": 2380000, - "expectedDuration": 3600000, - "percent": 0.65, - "rate": 0.74, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T18:00:00", - "duration": 3600000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-05-31T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T18:39:40", - "duration": 12020000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T22:00:00", - "duration": 1941000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T22:32:21", - "duration": 332000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T22:37:53", - "duration": 4927000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T00:00:00", - "duration": 7844000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T02:10:44", - "duration": 5400000, - "percent": 0.6, - "rate": 0.9, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T02:10:44", - "duration": 5400000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-06-01T09:11:42Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T02:10:44", - "duration": 4756000, - "expectedDuration": 5400000, - "percent": 0.6, - "rate": 0.9, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T02:10:44", - "duration": 5400000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-06-01T09:11:42Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T03:30:00", - "duration": 5400000, - "percent": 0.6, - "rate": 0.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T03:30:00", - "duration": 5400000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-06-01T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T03:30:00", - "duration": 644000, - "expectedDuration": 5400000, - "percent": 0.6, - "rate": 0.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T03:30:00", - "duration": 5400000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-06-01T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T03:40:44", - "duration": 6556000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T22:00:00", - "duration": 89000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T22:01:29", - "duration": 427000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T22:08:36", - "duration": 6684000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T12:00:00", - "duration": 6521000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:48:41", - "duration": 180000, - "percent": 0.6, - "rate": 0.39, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:48:41", - "duration": 180000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-06-03T20:49:39Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:48:41", - "duration": 154000, - "expectedDuration": 180000, - "percent": 0.6, - "rate": 0.39, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:48:41", - "duration": 180000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-06-03T20:49:39Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:51:15", - "duration": 329000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:56:44", - "duration": 5400000, - "percent": 1.2, - "rate": 0.78, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:56:44", - "duration": 5400000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-06-03T20:57:42Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T15:26:44", - "duration": 9196000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T00:00:00", - "duration": 2718000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T00:45:18", - "duration": 410000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T00:52:08", - "duration": 9472000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T18:00:00", - "duration": 9098000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T20:31:38", - "duration": 238000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T20:35:36", - "duration": 5064000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T12:00:00", - "duration": 6090000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T13:41:30", - "duration": 277000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T13:46:07", - "duration": 8525000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-07T15:08:12", - "duration": 13000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T16:08:25", - "duration": 10295000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-07T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T12:00:00", - "duration": 537000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T12:08:57", - "duration": 190000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T12:12:07", - "duration": 20873000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T12:00:00", - "duration": 3798000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T13:03:18", - "duration": 482000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T14:12:18", - "duration": 13662000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T03:30:00", - "duration": 3971000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T04:36:11", - "duration": 250000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T04:40:21", - "duration": 2979000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T22:00:00", - "duration": 3091000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T22:51:31", - "duration": 1929000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T23:23:40", - "duration": 2180000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T12:00:00", - "duration": 2125000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T12:35:25", - "duration": 1737000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T13:04:22", - "duration": 17738000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T00:00:00", - "duration": 1723000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T00:28:43", - "duration": 27000000, - "percent": 0.65, - "rate": 0.97, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T00:28:43", - "duration": 27000000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-06-15T07:28:43Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T00:28:43", - "duration": 10877000, - "expectedDuration": 27000000, - "percent": 0.65, - "rate": 0.97, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T00:28:43", - "duration": 27000000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-06-15T07:28:43Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T03:30:00", - "duration": 27000000, - "percent": 0.65, - "rate": 0.87, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T03:30:00", - "duration": 27000000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-06-15T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T03:30:00", - "duration": 7200000, - "expectedDuration": 27000000, - "percent": 0.65, - "rate": 0.87, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T03:30:00", - "duration": 27000000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-06-15T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T05:30:00", - "duration": 27000000, - "percent": 0.65, - "rate": 1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T05:30:00", - "duration": 27000000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-06-15T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T05:30:00", - "duration": 8923000, - "expectedDuration": 27000000, - "percent": 0.65, - "rate": 1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T05:30:00", - "duration": 27000000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-06-15T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T07:58:43", - "duration": 1877000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T12:00:00", - "duration": 11186000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T15:06:26", - "duration": 10709000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T18:04:55", - "duration": 14105000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T08:30:00", - "duration": 7555000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T10:35:55", - "duration": 27000000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T10:35:55", - "duration": 27000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-06-18T17:35:55Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T10:35:55", - "duration": 5045000, - "expectedDuration": 27000000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T10:35:55", - "duration": 27000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-06-18T17:35:55Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T12:00:00", - "duration": 27000000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T12:00:00", - "duration": 27000000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-06-18T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T12:00:00", - "duration": 21600000, - "expectedDuration": 27000000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T12:00:00", - "duration": 27000000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-06-18T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T18:00:00", - "duration": 27000000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T18:00:00", - "duration": 27000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-06-19T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T18:00:00", - "duration": 354000, - "expectedDuration": 27000000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T18:00:00", - "duration": 27000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-06-19T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T18:05:54", - "duration": 6111000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T19:47:45", - "duration": 18000000, - "percent": 0.85, - "rate": 0.97, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T19:47:45", - "duration": 18000000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-06-19T02:47:45Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T19:47:45", - "duration": 7935000, - "expectedDuration": 18000000, - "percent": 0.85, - "rate": 0.97, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T19:47:45", - "duration": 18000000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-06-19T02:47:45Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T22:00:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.23, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T22:00:00", - "duration": 18000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-06-19T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T22:00:00", - "duration": 7200000, - "expectedDuration": 18000000, - "percent": 0.85, - "rate": 1.23, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T22:00:00", - "duration": 18000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-06-19T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T00:00:00", - "duration": 17880000, - "percent": 0.85, - "rate": 1.27, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T00:00:00", - "duration": 17880000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-06-19T07:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T00:00:00", - "duration": 2696000, - "expectedDuration": 17880000, - "percent": 0.85, - "rate": 1.27, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T00:00:00", - "duration": 17880000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-06-19T07:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T00:44:56", - "duration": 112000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T00:46:48", - "duration": 9792000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T18:00:00", - "duration": 10769000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T20:59:29", - "duration": 3631000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T08:30:00", - "duration": 10621000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T11:27:01", - "duration": 25200000, - "percent": 0.8, - "rate": 1.12, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T11:27:01", - "duration": 25200000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-06-21T18:27:01Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T11:27:01", - "duration": 1979000, - "expectedDuration": 25200000, - "percent": 0.8, - "rate": 1.12, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T11:27:01", - "duration": 25200000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-06-21T18:27:01Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T12:00:00", - "duration": 14160000, - "percent": 0.8, - "rate": 0.48, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T12:00:00", - "duration": 14160000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-06-21T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T12:00:00", - "duration": 12135000, - "expectedDuration": 14160000, - "percent": 0.8, - "rate": 0.48, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T12:00:00", - "duration": 14160000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-06-21T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T15:22:15", - "duration": 52000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T18:23:07", - "duration": 13013000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T22:00:00", - "duration": 6238000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T23:43:58", - "duration": 870000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T23:58:28", - "duration": 92000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T00:00:00", - "duration": 9249000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T02:34:09", - "duration": 9000000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T02:34:09", - "duration": 9000000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-06-24T06:34:09Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T02:34:09", - "duration": 3351000, - "expectedDuration": 9000000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T02:34:09", - "duration": 9000000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-06-24T06:34:09Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T03:30:00", - "duration": 9000000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T03:30:00", - "duration": 9000000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-06-24T07:30:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T03:30:00", - "duration": 5649000, - "expectedDuration": 9000000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T03:30:00", - "duration": 9000000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-06-24T07:30:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T05:04:09", - "duration": 1551000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T08:30:00", - "duration": 6845000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T10:24:05", - "duration": 10800000, - "percent": 1.35, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T10:24:05", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-06-24T14:24:05Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T10:24:05", - "duration": 5755000, - "expectedDuration": 10800000, - "percent": 1.35, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T10:24:05", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-06-24T14:24:05Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T12:00:00", - "duration": 10800000, - "percent": 1.35, - "rate": 0.81, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T12:00:00", - "duration": 10800000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-06-24T16:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T12:00:00", - "duration": 5045000, - "expectedDuration": 10800000, - "percent": 1.35, - "rate": 0.81, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T12:00:00", - "duration": 10800000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-06-24T16:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T13:24:05", - "duration": 16555000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T05:30:00", - "duration": 8167000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T07:46:07", - "duration": 5319000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T09:14:46", - "duration": 9914000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T22:00:00", - "duration": 2939000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T22:48:59", - "duration": 3600000, - "percent": 0.85, - "rate": 1.19, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T22:48:59", - "duration": 3600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-06-26T02:48:59Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T23:48:59", - "duration": 661000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T00:00:00", - "duration": 10930000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T03:02:10", - "duration": 56000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T00:03:06", - "duration": 12414000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T12:00:00", - "duration": 16156000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T16:29:16", - "duration": 5400000, - "percent": 1.4, - "rate": 0.84, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T16:29:16", - "duration": 5400000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-06-27T23:29:16Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T17:59:16", - "duration": 44000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T12:00:00", - "duration": 7901000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T14:11:41", - "duration": 1866000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T14:42:47", - "duration": 11833000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T08:30:00", - "duration": 7554000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T10:35:54", - "duration": 27000000, - "percent": 0.85, - "rate": 1.19, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T10:35:54", - "duration": 27000000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-06-29T17:35:54Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T10:35:54", - "duration": 5046000, - "expectedDuration": 27000000, - "percent": 0.85, - "rate": 1.19, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T10:35:54", - "duration": 27000000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-06-29T17:35:54Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T12:00:00", - "duration": 27000000, - "percent": 0.85, - "rate": 0.51, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T12:00:00", - "duration": 27000000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-06-29T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T12:00:00", - "duration": 21600000, - "expectedDuration": 27000000, - "percent": 0.85, - "rate": 0.51, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T12:00:00", - "duration": 27000000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-06-29T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T18:00:00", - "duration": 27000000, - "percent": 0.85, - "rate": 0.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T18:00:00", - "duration": 27000000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-06-30T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T18:00:00", - "duration": 354000, - "expectedDuration": 27000000, - "percent": 0.85, - "rate": 0.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T18:00:00", - "duration": 27000000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-06-30T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T18:05:54", - "duration": 14046000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T22:00:00", - "duration": 5283000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T23:28:03", - "duration": 3855000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T00:32:18", - "duration": 10662000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T18:00:00", - "duration": 6951000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T19:55:51", - "duration": 7449000, - "rate": 1, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T22:00:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T05:30:00", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T08:30:00", - "duration": 10564000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T11:26:04", - "duration": 139000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T11:28:23", - "duration": 1897000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T00:00:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T03:30:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T00:00:00", - "duration": 11060000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:04:20", - "duration": 21600000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:04:20", - "duration": 21600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-07-03T10:04:20Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:04:20", - "duration": 1540000, - "expectedDuration": 21600000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:04:20", - "duration": 21600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-07-03T10:04:20Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:30:00", - "duration": 21600000, - "percent": 0.75, - "rate": 0.93, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:30:00", - "duration": 21600000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-07-03T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:30:00", - "duration": 7200000, - "expectedDuration": 21600000, - "percent": 0.75, - "rate": 0.93, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:30:00", - "duration": 21600000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-07-03T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T05:30:00", - "duration": 19560000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T05:30:00", - "duration": 19560000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-07-03T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T05:30:00", - "duration": 10631000, - "expectedDuration": 19560000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T05:30:00", - "duration": 19560000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-07-03T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T08:27:11", - "duration": 10538000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T11:22:49", - "duration": 2231000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T00:00:00", - "duration": 10459000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T02:54:19", - "duration": 7200000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T02:54:19", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-07-04T09:54:19Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T02:54:19", - "duration": 2141000, - "expectedDuration": 7200000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T02:54:19", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-07-04T09:54:19Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T03:30:00", - "duration": 7200000, - "percent": 0.75, - "rate": 0.93, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T03:30:00", - "duration": 7200000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-07-04T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T03:30:00", - "duration": 5059000, - "expectedDuration": 7200000, - "percent": 0.75, - "rate": 0.93, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T03:30:00", - "duration": 7200000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-07-04T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T04:54:19", - "duration": 2141000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T00:00:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T03:30:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T00:00:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T03:30:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T18:00:00", - "duration": 4501000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T19:15:01", - "duration": 442000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T19:22:23", - "duration": 9457000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T00:00:00", - "duration": 9207000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T02:33:27", - "duration": 3600000, - "percent": 1.35, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T02:33:27", - "duration": 3600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-07-07T09:33:27Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T02:33:27", - "duration": 3393000, - "expectedDuration": 3600000, - "percent": 1.35, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T02:33:27", - "duration": 3600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-07-07T09:33:27Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T03:30:00", - "duration": 3600000, - "percent": 1.35, - "rate": 1.68, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T03:30:00", - "duration": 3600000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-07-07T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T03:30:00", - "duration": 207000, - "expectedDuration": 3600000, - "percent": 1.35, - "rate": 1.68, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T03:30:00", - "duration": 3600000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-07-07T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T03:33:27", - "duration": 6993000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T00:00:00", - "duration": 7931000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T02:12:11", - "duration": 1802000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T02:42:13", - "duration": 2867000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T00:00:00", - "duration": 1644000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T00:27:24", - "duration": 387000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T00:33:51", - "duration": 10569000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T05:30:00", - "duration": 11850000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T08:47:30", - "duration": 7734000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T10:56:24", - "duration": 3816000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T12:00:00", - "duration": 11503000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T15:11:43", - "duration": 238000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T15:15:41", - "duration": 9859000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T00:00:00", - "duration": 11695000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:14:55", - "duration": 18000000, - "percent": 0.85, - "rate": 1.1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:14:55", - "duration": 18000000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-07-15T10:14:55Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:14:55", - "duration": 905000, - "expectedDuration": 18000000, - "percent": 0.85, - "rate": 1.1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:14:55", - "duration": 18000000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-07-15T10:14:55Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:30:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.02, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:30:00", - "duration": 18000000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-07-15T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:30:00", - "duration": 7200000, - "expectedDuration": 18000000, - "percent": 0.85, - "rate": 1.02, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:30:00", - "duration": 18000000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-07-15T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T05:30:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T05:30:00", - "duration": 18000000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-07-15T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T05:30:00", - "duration": 9895000, - "expectedDuration": 18000000, - "percent": 0.85, - "rate": 1.1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T05:30:00", - "duration": 18000000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-07-15T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T08:14:55", - "duration": 905000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T08:30:00", - "duration": 4149000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T09:39:09", - "duration": 6405000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T11:25:54", - "duration": 2046000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T12:00:00", - "duration": 10914000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T15:01:54", - "duration": 3600000, - "percent": 1.25, - "rate": 0.56, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T15:01:54", - "duration": 3600000, - "rate": 0.45, - "scheduleName": "basal 3", - "time": "2018-07-17T22:01:54Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T16:01:54", - "duration": 7086000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T12:00:00", - "duration": 14774000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T16:06:14", - "duration": 789000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T16:19:23", - "duration": 6037000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T18:00:00", - "duration": 5447000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T19:30:47", - "duration": 10800000, - "percent": 1.15, - "rate": 1.03, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T19:30:47", - "duration": 10800000, - "rate": 0.9, - "scheduleName": "basal 3", - "time": "2018-07-20T02:30:47Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T19:30:47", - "duration": 8953000, - "expectedDuration": 10800000, - "percent": 1.15, - "rate": 1.03, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T19:30:47", - "duration": 10800000, - "rate": 0.9, - "scheduleName": "basal 3", - "time": "2018-07-20T02:30:47Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T22:00:00", - "duration": 10800000, - "percent": 1.15, - "rate": 1.43, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T22:00:00", - "duration": 10800000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-07-20T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T22:00:00", - "duration": 1847000, - "expectedDuration": 10800000, - "percent": 1.15, - "rate": 1.43, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T22:00:00", - "duration": 10800000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-07-20T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T22:30:47", - "duration": 5353000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T00:00:00", - "duration": 7351000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T02:02:31", - "duration": 5400000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T02:02:31", - "duration": 5400000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-07-22T09:02:31Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T02:02:31", - "duration": 5249000, - "expectedDuration": 5400000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T02:02:31", - "duration": 5400000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-07-22T09:02:31Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T03:30:00", - "duration": 5400000, - "percent": 0.8, - "rate": 0.96, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T03:30:00", - "duration": 5400000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-07-22T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T03:30:00", - "duration": 151000, - "expectedDuration": 5400000, - "percent": 0.8, - "rate": 0.96, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T03:30:00", - "duration": 5400000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-07-22T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T03:32:31", - "duration": 7049000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T00:00:00", - "duration": 829000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T00:13:49", - "duration": 2232000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T00:51:01", - "duration": 9539000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T08:30:00", - "duration": 1596000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T08:56:36", - "duration": 882000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T09:11:18", - "duration": 10122000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T18:00:00", - "duration": 124000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T18:02:04", - "duration": 5400000, - "percent": 0.85, - "rate": 0.76, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T18:02:04", - "duration": 5400000, - "rate": 0.89, - "scheduleName": "basal 3", - "time": "2018-07-27T01:02:04Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T19:32:04", - "duration": 8876000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T00:00:00", - "duration": 860000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T00:14:20", - "duration": 2644000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T00:58:24", - "duration": 9096000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T18:00:00", - "duration": 1335000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T18:22:15", - "duration": 5400000, - "percent": 0.4, - "rate": 0.36, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T18:22:15", - "duration": 5400000, - "rate": 0.9, - "scheduleName": "basal 3", - "time": "2018-07-31T01:22:15Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T19:52:15", - "duration": 7665000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T00:00:00", - "duration": 7906000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T02:11:46", - "duration": 21445000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T08:09:11", - "duration": 1249000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T00:00:00", - "duration": 6044000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T01:40:44", - "duration": 5880000, - "percent": 0.85, - "rate": 1.1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T01:40:44", - "duration": 5880000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-08-03T08:40:44Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T01:40:44", - "duration": 5867000, - "expectedDuration": 5880000, - "percent": 0.85, - "rate": 1.1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T01:40:44", - "duration": 5880000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-08-03T08:40:44Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:18:31", - "duration": 9000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:18:40", - "duration": 7200000, - "percent": 0.7, - "rate": 0.91, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:18:40", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-08-03T10:18:40Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:18:40", - "duration": 680000, - "expectedDuration": 7200000, - "percent": 0.7, - "rate": 0.91, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:18:40", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-08-03T10:18:40Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:30:00", - "duration": 7200000, - "percent": 0.7, - "rate": 0.84, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-08-03T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:30:00", - "duration": 6520000, - "expectedDuration": 7200000, - "percent": 0.7, - "rate": 0.84, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-08-03T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T05:18:40", - "duration": 680000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T12:00:00", - "duration": 8453000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T14:20:53", - "duration": 326000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T14:26:19", - "duration": 12821000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T12:00:00", - "duration": 18803000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T17:13:23", - "duration": 7200000, - "percent": 1.25, - "rate": 0.56, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T17:13:23", - "duration": 7200000, - "rate": 0.45, - "scheduleName": "basal 3", - "time": "2018-08-06T00:13:23Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T17:13:23", - "duration": 2797000, - "expectedDuration": 7200000, - "percent": 1.25, - "rate": 0.56, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T17:13:23", - "duration": 7200000, - "rate": 0.45, - "scheduleName": "basal 3", - "time": "2018-08-06T00:13:23Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T18:00:00", - "duration": 7200000, - "percent": 1.25, - "rate": 1.12, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T18:00:00", - "duration": 7200000, - "rate": 0.9, - "scheduleName": "basal 3", - "time": "2018-08-06T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T18:00:00", - "duration": 4403000, - "expectedDuration": 7200000, - "percent": 1.25, - "rate": 1.12, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T18:00:00", - "duration": 7200000, - "rate": 0.9, - "scheduleName": "basal 3", - "time": "2018-08-06T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T19:13:23", - "duration": 9106000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T21:45:09", - "duration": 251000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T21:49:20", - "duration": 640000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T05:30:00", - "duration": 9183000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T08:03:03", - "duration": 1617000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T03:30:00", - "duration": 5472000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T05:01:12", - "duration": 180000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T05:04:12", - "duration": 1548000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T18:00:00", - "duration": 13178000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T21:39:38", - "duration": 3600000, - "percent": 1.15, - "rate": 1.2, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T21:39:38", - "duration": 3600000, - "rate": 1.04, - "scheduleName": "basal 3", - "time": "2018-08-12T04:39:38Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T21:39:38", - "duration": 1222000, - "expectedDuration": 3600000, - "percent": 1.15, - "rate": 1.2, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T21:39:38", - "duration": 3600000, - "rate": 1.04, - "scheduleName": "basal 3", - "time": "2018-08-12T04:39:38Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T22:00:00", - "duration": 3600000, - "percent": 1.15, - "rate": 1.61, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T22:00:00", - "duration": 3600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-08-12T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T22:00:00", - "duration": 2378000, - "expectedDuration": 3600000, - "percent": 1.15, - "rate": 1.61, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T22:00:00", - "duration": 3600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-08-12T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T22:39:38", - "duration": 4822000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T12:00:00", - "duration": 4236000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T13:10:36", - "duration": 3620000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T14:10:56", - "duration": 3631000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T15:11:27", - "duration": 600000, - "percent": 0.8, - "rate": 0.48, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T15:11:27", - "duration": 600000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-08-12T22:11:27Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T15:11:27", - "duration": 588000, - "expectedDuration": 600000, - "percent": 0.8, - "rate": 0.48, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T15:11:27", - "duration": 600000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-08-12T22:11:27Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T15:21:15", - "duration": 7934000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T17:33:29", - "duration": 1591000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T00:00:00", - "duration": 8499000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T02:21:39", - "duration": 16200000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T02:21:39", - "duration": 16200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-08-14T09:21:39Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T02:21:39", - "duration": 4101000, - "expectedDuration": 16200000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T02:21:39", - "duration": 16200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-08-14T09:21:39Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T03:30:00", - "duration": 16200000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T03:30:00", - "duration": 16200000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-08-14T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T03:30:00", - "duration": 7200000, - "expectedDuration": 16200000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T03:30:00", - "duration": 16200000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-08-14T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T05:30:00", - "duration": 16200000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T05:30:00", - "duration": 16200000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-08-14T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T05:30:00", - "duration": 4899000, - "expectedDuration": 16200000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T05:30:00", - "duration": 16200000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-08-14T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T06:51:39", - "duration": 5901000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T18:00:00", - "duration": 3812000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T19:03:32", - "duration": 6060000, - "percent": 0.75, - "rate": 0.78, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T19:03:32", - "duration": 6060000, - "rate": 1.04, - "scheduleName": "basal 3", - "time": "2018-08-15T02:03:32Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T19:03:32", - "duration": 6031000, - "expectedDuration": 6060000, - "percent": 0.75, - "rate": 0.78, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T19:03:32", - "duration": 6060000, - "rate": 1.04, - "scheduleName": "basal 3", - "time": "2018-08-15T02:03:32Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T20:44:03", - "duration": 9000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T20:44:12", - "duration": 5400000, - "percent": 0.65, - "rate": 0.68, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T20:44:12", - "duration": 5400000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-08-15T03:44:12Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T20:44:12", - "duration": 4548000, - "expectedDuration": 5400000, - "percent": 0.65, - "rate": 0.68, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T20:44:12", - "duration": 5400000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-08-15T03:44:12Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T22:00:00", - "duration": 5400000, - "percent": 0.65, - "rate": 0.91, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T22:00:00", - "duration": 5400000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-08-15T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T22:00:00", - "duration": 852000, - "expectedDuration": 5400000, - "percent": 0.65, - "rate": 0.91, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T22:00:00", - "duration": 5400000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-08-15T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T22:14:12", - "duration": 6348000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T08:30:00", - "duration": 7596000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T10:36:36", - "duration": 5004000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T18:00:00", - "duration": 57000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T18:00:57", - "duration": 10800000, - "percent": 0.19999999999999996, - "rate": 0.18, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T18:00:57", - "duration": 10800000, - "rate": 0.9, - "scheduleName": "basal 3", - "time": "2018-08-16T01:00:57Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T21:00:57", - "duration": 2953000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T21:50:10", - "duration": 240000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T21:54:10", - "duration": 350000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T05:30:00", - "duration": 1539000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T05:55:39", - "duration": 255000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T05:59:54", - "duration": 9006000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T12:00:00", - "duration": 19916000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T17:31:56", - "duration": 9000000, - "percent": 0.6, - "rate": 0.27, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T17:31:56", - "duration": 9000000, - "rate": 0.45, - "scheduleName": "basal 3", - "time": "2018-08-21T00:31:56Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T17:31:56", - "duration": 1684000, - "expectedDuration": 9000000, - "percent": 0.6, - "rate": 0.27, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T17:31:56", - "duration": 9000000, - "rate": 0.45, - "scheduleName": "basal 3", - "time": "2018-08-21T00:31:56Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T18:00:00", - "duration": 9000000, - "percent": 0.6, - "rate": 0.54, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T18:00:00", - "duration": 9000000, - "rate": 0.9, - "scheduleName": "basal 3", - "time": "2018-08-21T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T18:00:00", - "duration": 7316000, - "expectedDuration": 9000000, - "percent": 0.6, - "rate": 0.54, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T18:00:00", - "duration": 9000000, - "rate": 0.9, - "scheduleName": "basal 3", - "time": "2018-08-21T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T20:01:56", - "duration": 7084000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T12:00:00", - "duration": 12721000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T15:32:01", - "duration": 1800000, - "percent": 0.7, - "rate": 0.31, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T15:32:01", - "duration": 1800000, - "rate": 0.44, - "scheduleName": "basal 3", - "time": "2018-08-21T22:32:01Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T16:02:01", - "duration": 7079000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T12:00:00", - "duration": 6854000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T13:54:14", - "duration": 473000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T14:02:07", - "duration": 14273000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T00:00:00", - "duration": 11831000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:17:11", - "duration": 25200000, - "percent": 0.75, - "rate": 0.97, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:17:11", - "duration": 25200000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-08-23T10:17:11Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:17:11", - "duration": 769000, - "expectedDuration": 25200000, - "percent": 0.75, - "rate": 0.97, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:17:11", - "duration": 25200000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-08-23T10:17:11Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:30:00", - "duration": 25200000, - "percent": 0.75, - "rate": 0.9, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:30:00", - "duration": 25200000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-08-23T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:30:00", - "duration": 7200000, - "expectedDuration": 25200000, - "percent": 0.75, - "rate": 0.9, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:30:00", - "duration": 25200000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-08-23T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T05:30:00", - "duration": 25200000, - "percent": 0.75, - "rate": 0.97, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T05:30:00", - "duration": 25200000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-08-23T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T05:30:00", - "duration": 10800000, - "expectedDuration": 25200000, - "percent": 0.75, - "rate": 0.97, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T05:30:00", - "duration": 25200000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-08-23T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T08:30:00", - "duration": 25200000, - "percent": 0.75, - "rate": 0.93, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T08:30:00", - "duration": 25200000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-08-23T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T08:30:00", - "duration": 6431000, - "expectedDuration": 25200000, - "percent": 0.75, - "rate": 0.93, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T08:30:00", - "duration": 25200000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-08-23T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T10:17:11", - "duration": 6169000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T00:00:00", - "duration": 7034000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T01:57:14", - "duration": 25200000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T01:57:14", - "duration": 25200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-08-24T08:57:14Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T01:57:14", - "duration": 5566000, - "expectedDuration": 25200000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T01:57:14", - "duration": 25200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-08-24T08:57:14Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T03:30:00", - "duration": 25200000, - "percent": 0.8, - "rate": 0.96, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T03:30:00", - "duration": 25200000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-08-24T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T03:30:00", - "duration": 7200000, - "expectedDuration": 25200000, - "percent": 0.8, - "rate": 0.96, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T03:30:00", - "duration": 25200000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-08-24T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T05:30:00", - "duration": 25200000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T05:30:00", - "duration": 25200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-08-24T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T05:30:00", - "duration": 10800000, - "expectedDuration": 25200000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T05:30:00", - "duration": 25200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-08-24T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T08:30:00", - "duration": 25200000, - "percent": 0.8, - "rate": 1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T08:30:00", - "duration": 25200000, - "rate": 1.25, - "scheduleName": "basal 3", - "time": "2018-08-24T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T08:30:00", - "duration": 1634000, - "expectedDuration": 25200000, - "percent": 0.8, - "rate": 1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T08:30:00", - "duration": 25200000, - "rate": 1.25, - "scheduleName": "basal 3", - "time": "2018-08-24T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T08:57:14", - "duration": 10966000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T12:00:00", - "duration": 8532000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T14:22:12", - "duration": 7200000, - "percent": 0.30000000000000004, - "rate": 0.13, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T14:22:12", - "duration": 7200000, - "rate": 0.43, - "scheduleName": "basal 3", - "time": "2018-08-24T21:22:12Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T16:22:12", - "duration": 5868000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T18:00:00", - "duration": 14095000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T21:54:55", - "duration": 280000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T21:59:35", - "duration": 25000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T03:30:00", - "duration": 6075000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T05:11:15", - "duration": 397000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T05:17:52", - "duration": 728000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T12:00:00", - "duration": 4392000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T13:13:12", - "duration": 17592000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T18:06:24", - "duration": 14016000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T08:30:00", - "duration": 9169000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T11:02:49", - "duration": 3431000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T05:30:00", - "duration": 4177000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T06:39:37", - "duration": 10025000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T09:26:42", - "duration": 9198000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T12:00:00", - "duration": 19217000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T17:20:17", - "duration": 6688000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T19:11:45", - "duration": 10095000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T00:00:00", - "duration": 1827000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T00:30:27", - "duration": 1374000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T00:53:21", - "duration": 9399000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T08:30:00", - "duration": 2264000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T09:07:44", - "duration": 7415000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T11:11:19", - "duration": 1593000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T11:37:52", - "duration": 5400000, - "percent": 1.35, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T11:37:52", - "duration": 5400000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-09-14T18:37:52Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T11:37:52", - "duration": 1328000, - "expectedDuration": 5400000, - "percent": 1.35, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T11:37:52", - "duration": 5400000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-09-14T18:37:52Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T12:00:00", - "duration": 5400000, - "percent": 1.35, - "rate": 0.81, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T12:00:00", - "duration": 5400000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-14T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T12:00:00", - "duration": 4072000, - "expectedDuration": 5400000, - "percent": 1.35, - "rate": 0.81, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T12:00:00", - "duration": 5400000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-14T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T13:07:52", - "duration": 17528000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T12:00:00", - "duration": 142000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T12:02:22", - "duration": 3600000, - "percent": 0.7, - "rate": 0.42, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T12:02:22", - "duration": 3600000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-15T19:02:22Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T13:02:22", - "duration": 17858000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T08:30:00", - "duration": 5863000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T10:07:43", - "duration": 5400000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T10:07:43", - "duration": 5400000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-09-16T17:07:43Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T11:37:43", - "duration": 1337000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T18:00:00", - "duration": 4181000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T19:09:41", - "duration": 3495000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T20:07:56", - "duration": 6724000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T12:00:00", - "duration": 5103000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T13:25:03", - "duration": 76000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T13:26:19", - "duration": 16421000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T18:00:00", - "duration": 13638000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T21:47:18", - "duration": 533000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T21:56:11", - "duration": 229000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T18:00:00", - "duration": 2999000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T18:49:59", - "duration": 3600000, - "percent": 1.45, - "rate": 1.52, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T18:49:59", - "duration": 3600000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-09-21T01:49:59Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T19:49:59", - "duration": 7801000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T00:00:00", - "duration": 2319000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T00:38:39", - "duration": 7200000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T00:38:39", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-09-21T07:38:39Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T02:38:39", - "duration": 3081000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T00:00:00", - "duration": 1518000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T00:25:18", - "duration": 3600000, - "percent": 0.7, - "rate": 1.05, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T00:25:18", - "duration": 3600000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-09-22T07:25:18Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T01:25:18", - "duration": 7482000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T05:30:00", - "duration": 1230000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T05:50:30", - "duration": 18830000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T11:04:20", - "duration": 3340000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T12:00:00", - "duration": 19246000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T17:20:46", - "duration": 7200000, - "percent": 1.7, - "rate": 1.02, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T17:20:46", - "duration": 7200000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-24T00:20:46Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T17:20:46", - "duration": 2354000, - "expectedDuration": 7200000, - "percent": 1.7, - "rate": 1.02, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T17:20:46", - "duration": 7200000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-24T00:20:46Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T18:00:00", - "duration": 7200000, - "percent": 1.7, - "rate": 1.78, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T18:00:00", - "duration": 7200000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-09-24T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T18:00:00", - "duration": 4846000, - "expectedDuration": 7200000, - "percent": 1.7, - "rate": 1.78, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T18:00:00", - "duration": 7200000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-09-24T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T19:20:46", - "duration": 9554000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T08:30:00", - "duration": 2085000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T09:04:45", - "duration": 4217000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T10:15:02", - "duration": 6298000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T12:00:00", - "duration": 17944000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T16:59:04", - "duration": 3600000, - "percent": 1.65, - "rate": 0.99, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T16:59:04", - "duration": 3600000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-26T23:59:04Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T17:59:04", - "duration": 56000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T18:00:00", - "duration": 5666000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T19:34:26", - "duration": 5400000, - "percent": 1.9, - "rate": 1.99, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T19:34:26", - "duration": 5400000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-09-27T02:34:26Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T21:04:26", - "duration": 3334000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T00:00:00", - "duration": 2082000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T00:34:42", - "duration": 3600000, - "percent": 1.35, - "rate": 2.02, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T00:34:42", - "duration": 3600000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-09-27T07:34:42Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T01:34:42", - "duration": 6918000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T12:00:00", - "duration": 5752000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T13:35:52", - "duration": 204000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T13:39:16", - "duration": 5345000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T15:08:21", - "duration": 5400000, - "percent": 1.55, - "rate": 0.93, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T15:08:21", - "duration": 5400000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-27T22:08:21Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T16:38:21", - "duration": 4899000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T18:00:00", - "duration": 6720000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T19:52:00", - "duration": 645000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T20:02:45", - "duration": 7035000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T05:30:00", - "duration": 9805000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:13:25", - "duration": 5400000, - "percent": 1.5, - "rate": 2.32, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:13:25", - "duration": 5400000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-09-28T15:13:25Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:13:25", - "duration": 995000, - "expectedDuration": 5400000, - "percent": 1.5, - "rate": 2.32, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:13:25", - "duration": 5400000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-09-28T15:13:25Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:30:00", - "duration": 5400000, - "percent": 1.5, - "rate": 2.1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:30:00", - "duration": 5400000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-09-28T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:30:00", - "duration": 4405000, - "expectedDuration": 5400000, - "percent": 1.5, - "rate": 2.1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:30:00", - "duration": 5400000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-09-28T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T09:43:25", - "duration": 8195000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T12:00:00", - "duration": 2532000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T12:42:12", - "duration": 4620000, - "percent": 1.4, - "rate": 0.84, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T12:42:12", - "duration": 4620000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-28T19:42:12Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T12:42:12", - "duration": 4596000, - "expectedDuration": 4620000, - "percent": 1.4, - "rate": 0.84, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T12:42:12", - "duration": 4620000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-28T19:42:12Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T13:58:48", - "duration": 14000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T13:59:02", - "duration": 5400000, - "percent": 1.55, - "rate": 0.93, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T13:59:02", - "duration": 5400000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-28T20:59:02Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T15:29:02", - "duration": 6819000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T17:22:41", - "duration": 7200000, - "percent": 1.35, - "rate": 0.81, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T17:22:41", - "duration": 7200000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-29T00:22:41Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T17:22:41", - "duration": 2239000, - "expectedDuration": 7200000, - "percent": 1.35, - "rate": 0.81, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T17:22:41", - "duration": 7200000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-29T00:22:41Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T18:00:00", - "duration": 7200000, - "percent": 1.35, - "rate": 1.41, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T18:00:00", - "duration": 7200000, - "rate": 1.04, - "scheduleName": "basal 3", - "time": "2018-09-29T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T18:00:00", - "duration": 4961000, - "expectedDuration": 7200000, - "percent": 1.35, - "rate": 1.41, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T18:00:00", - "duration": 7200000, - "rate": 1.04, - "scheduleName": "basal 3", - "time": "2018-09-29T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T19:22:41", - "duration": 9439000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T00:00:00", - "duration": 9113000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T02:31:53", - "duration": 5400000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T02:31:53", - "duration": 5400000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-09-29T09:31:53Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T02:31:53", - "duration": 3487000, - "expectedDuration": 5400000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T02:31:53", - "duration": 5400000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-09-29T09:31:53Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T03:30:00", - "duration": 5400000, - "percent": 1.25, - "rate": 1.68, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T03:30:00", - "duration": 5400000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-09-29T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T03:30:00", - "duration": 1913000, - "expectedDuration": 5400000, - "percent": 1.25, - "rate": 1.68, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T03:30:00", - "duration": 5400000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-09-29T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T04:01:53", - "duration": 5287000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T08:30:00", - "duration": 4914000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T09:51:54", - "duration": 9000000, - "percent": 0.8, - "rate": 1.12, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T09:51:54", - "duration": 9000000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-09-29T16:51:54Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T09:51:54", - "duration": 7686000, - "expectedDuration": 9000000, - "percent": 0.8, - "rate": 1.12, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T09:51:54", - "duration": 9000000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-09-29T16:51:54Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T12:00:00", - "duration": 9000000, - "percent": 0.8, - "rate": 0.48, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T12:00:00", - "duration": 9000000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-29T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T12:00:00", - "duration": 1314000, - "expectedDuration": 9000000, - "percent": 0.8, - "rate": 0.48, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T12:00:00", - "duration": 9000000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-29T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T12:21:54", - "duration": 20286000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T18:00:00", - "duration": 1416000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T18:23:36", - "duration": 10800000, - "percent": 1.5, - "rate": 1.57, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T18:23:36", - "duration": 10800000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-09-30T01:23:36Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T21:23:36", - "duration": 2184000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T08:30:00", - "duration": 3040000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T09:20:40", - "duration": 3159000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T10:13:19", - "duration": 6401000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T12:00:00", - "duration": 4788000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T13:19:48", - "duration": 7200000, - "percent": 1.45, - "rate": 0.87, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T13:19:48", - "duration": 7200000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-30T20:19:48Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T15:19:48", - "duration": 4339000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T16:32:07", - "duration": 7200000, - "percent": 1.5, - "rate": 0.9, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T16:32:07", - "duration": 7200000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-30T23:32:07Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T16:32:07", - "duration": 5273000, - "expectedDuration": 7200000, - "percent": 1.5, - "rate": 0.9, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T16:32:07", - "duration": 7200000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-30T23:32:07Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T18:00:00", - "duration": 7200000, - "percent": 1.5, - "rate": 1.57, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T18:00:00", - "duration": 7200000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-10-01T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T18:00:00", - "duration": 1927000, - "expectedDuration": 7200000, - "percent": 1.5, - "rate": 1.57, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T18:00:00", - "duration": 7200000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-10-01T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T18:32:07", - "duration": 12473000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T18:00:00", - "duration": 4755000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T19:19:15", - "duration": 9000000, - "percent": 1.5, - "rate": 1.57, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T19:19:15", - "duration": 9000000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-10-02T02:19:15Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T21:49:15", - "duration": 645000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T18:00:00", - "duration": 12431000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T21:27:11", - "duration": 10800000, - "percent": 1.95, - "rate": 2.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T21:27:11", - "duration": 10800000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-10-03T04:27:11Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T21:27:11", - "duration": 1969000, - "expectedDuration": 10800000, - "percent": 1.95, - "rate": 2.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T21:27:11", - "duration": 10800000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-10-03T04:27:11Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T22:00:00", - "duration": 10800000, - "percent": 1.95, - "rate": 2.73, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T22:00:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-03T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T22:00:00", - "duration": 7200000, - "expectedDuration": 10800000, - "percent": 1.95, - "rate": 2.73, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T22:00:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-03T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T00:00:00", - "duration": 10800000, - "percent": 1.95, - "rate": 2.92, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T00:00:00", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-10-03T07:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T00:00:00", - "duration": 1631000, - "expectedDuration": 10800000, - "percent": 1.95, - "rate": 2.92, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T00:00:00", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-10-03T07:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T00:27:11", - "duration": 10969000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T18:00:00", - "duration": 260000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T18:04:20", - "duration": 3314000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T18:59:34", - "duration": 7000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T18:59:41", - "duration": 45000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T19:00:26", - "duration": 10774000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T05:30:00", - "duration": 7859000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T07:40:59", - "duration": 36000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T07:41:35", - "duration": 2905000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T08:30:00", - "duration": 5764000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T10:06:04", - "duration": 7200000, - "percent": 1.25, - "rate": 1.75, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T10:06:04", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-04T17:06:04Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T10:06:04", - "duration": 6836000, - "expectedDuration": 7200000, - "percent": 1.25, - "rate": 1.75, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T10:06:04", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-04T17:06:04Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T12:00:00", - "duration": 7200000, - "percent": 1.25, - "rate": 0.75, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T12:00:00", - "duration": 7200000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-10-04T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T12:00:00", - "duration": 364000, - "expectedDuration": 7200000, - "percent": 1.25, - "rate": 0.75, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T12:00:00", - "duration": 7200000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-10-04T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T12:06:04", - "duration": 21236000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T08:30:00", - "duration": 11084000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T11:34:44", - "duration": 3600000, - "percent": 0.7, - "rate": 0.98, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T11:34:44", - "duration": 3600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-05T18:34:44Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T11:34:44", - "duration": 1516000, - "expectedDuration": 3600000, - "percent": 0.7, - "rate": 0.98, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T11:34:44", - "duration": 3600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-05T18:34:44Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T12:00:00", - "duration": 3600000, - "percent": 0.7, - "rate": 0.42, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T12:00:00", - "duration": 3600000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-10-05T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T12:00:00", - "duration": 2084000, - "expectedDuration": 3600000, - "percent": 0.7, - "rate": 0.42, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T12:00:00", - "duration": 3600000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-10-05T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T12:34:44", - "duration": 19516000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T12:00:00", - "duration": 12872000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T15:34:32", - "duration": 4983000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T16:57:35", - "duration": 3745000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T18:00:00", - "duration": 5583000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T19:33:03", - "duration": 7200000, - "percent": 1.55, - "rate": 1.62, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T19:33:03", - "duration": 7200000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-10-07T02:33:03Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T21:33:03", - "duration": 1617000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T00:00:00", - "duration": 2776000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T00:46:16", - "duration": 7200000, - "percent": 1.3, - "rate": 2.01, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T00:46:16", - "duration": 7200000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-10-07T07:46:16Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T02:46:16", - "duration": 2624000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T22:00:00", - "duration": 1978000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T22:32:58", - "duration": 14400000, - "percent": 1.75, - "rate": 2.45, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T22:32:58", - "duration": 14400000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-08T05:32:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T22:32:58", - "duration": 5222000, - "expectedDuration": 14400000, - "percent": 1.75, - "rate": 2.45, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T22:32:58", - "duration": 14400000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-08T05:32:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T00:00:00", - "duration": 14400000, - "percent": 1.75, - "rate": 2.71, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T00:00:00", - "duration": 14400000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-10-08T07:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T00:00:00", - "duration": 9178000, - "expectedDuration": 14400000, - "percent": 1.75, - "rate": 2.71, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T00:00:00", - "duration": 14400000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-10-08T07:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T02:32:58", - "duration": 3422000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T05:30:00", - "duration": 8216000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T07:46:56", - "duration": 670000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T07:58:06", - "duration": 9000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T07:58:15", - "duration": 3600000, - "percent": 1.45, - "rate": 2.24, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T07:58:15", - "duration": 3600000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-10-09T14:58:15Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T07:58:15", - "duration": 1905000, - "expectedDuration": 3600000, - "percent": 1.45, - "rate": 2.24, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T07:58:15", - "duration": 3600000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-10-09T14:58:15Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T08:30:00", - "duration": 3600000, - "percent": 1.45, - "rate": 2.03, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T08:30:00", - "duration": 3600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-09T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T08:30:00", - "duration": 1695000, - "expectedDuration": 3600000, - "percent": 1.45, - "rate": 2.03, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T08:30:00", - "duration": 3600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-09T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T08:58:15", - "duration": 10905000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T18:00:00", - "duration": 1977000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T18:32:57", - "duration": 4784000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T19:52:41", - "duration": 7639000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T08:30:00", - "duration": 993000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T08:46:33", - "duration": 11607000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T03:30:00", - "duration": 14251000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T07:27:31", - "duration": 3604000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T08:27:35", - "duration": 145000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T12:00:00", - "duration": 1528000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T12:25:28", - "duration": 5400000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T12:25:28", - "duration": 5400000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-10-12T19:25:28Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T12:25:28", - "duration": 5399000, - "expectedDuration": 5400000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T12:25:28", - "duration": 5400000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-10-12T19:25:28Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T13:55:27", - "duration": 14673000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:00:00", - "duration": 887000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:14:47", - "duration": 60000, - "percent": 0.6, - "rate": 0.99, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:14:47", - "duration": 60000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-13T07:14:47Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:14:47", - "duration": 17000, - "expectedDuration": 60000, - "percent": 0.6, - "rate": 0.99, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:14:47", - "duration": 60000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-13T07:14:47Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:15:04", - "duration": 23000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:15:27", - "duration": 3147000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T01:07:54", - "duration": 435000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T04:15:09", - "duration": 14000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T04:15:23", - "duration": 9240000, - "percent": 0.65, - "rate": 1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T04:15:23", - "duration": 9240000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-10-13T08:15:23Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T04:15:23", - "duration": 9089000, - "expectedDuration": 9240000, - "percent": 0.65, - "rate": 1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T04:15:23", - "duration": 9240000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-10-13T08:15:23Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T06:46:52", - "duration": 297000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T06:51:49", - "duration": 17000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T06:52:06", - "duration": 3600000, - "percent": 0.85, - "rate": 1.31, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T06:52:06", - "duration": 3600000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-10-13T10:52:06Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T07:52:06", - "duration": 2274000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T18:00:00", - "duration": 10401000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T20:53:21", - "duration": 16200000, - "percent": 1.65, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T20:53:21", - "duration": 16200000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-14T00:53:21Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T20:53:21", - "duration": 3999000, - "expectedDuration": 16200000, - "percent": 1.65, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T20:53:21", - "duration": 16200000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-14T00:53:21Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T22:00:00", - "duration": 16200000, - "percent": 1.65, - "rate": 2.39, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T22:00:00", - "duration": 16200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-14T02:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T22:00:00", - "duration": 7200000, - "expectedDuration": 16200000, - "percent": 1.65, - "rate": 2.39, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T22:00:00", - "duration": 16200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-14T02:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T00:00:00", - "duration": 16200000, - "percent": 1.65, - "rate": 2.72, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T00:00:00", - "duration": 16200000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-14T04:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T00:00:00", - "duration": 5001000, - "expectedDuration": 16200000, - "percent": 1.65, - "rate": 2.72, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T00:00:00", - "duration": 16200000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-14T04:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T01:23:21", - "duration": 566000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T01:32:47", - "duration": 12600000, - "percent": 1.65, - "rate": 2.72, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T01:32:47", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-14T05:32:47Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T01:32:47", - "duration": 7033000, - "expectedDuration": 12600000, - "percent": 1.65, - "rate": 2.72, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T01:32:47", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-14T05:32:47Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T03:30:00", - "duration": 12600000, - "percent": 1.65, - "rate": 2.55, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T03:30:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-10-14T07:30:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T03:30:00", - "duration": 5567000, - "expectedDuration": 12600000, - "percent": 1.65, - "rate": 2.55, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T03:30:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-10-14T07:30:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T05:02:47", - "duration": 12433000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T12:00:00", - "duration": 18910000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T17:15:10", - "duration": 10800000, - "percent": 1.45, - "rate": 0.94, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T17:15:10", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-14T21:15:10Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T17:15:10", - "duration": 2690000, - "expectedDuration": 10800000, - "percent": 1.45, - "rate": 0.94, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T17:15:10", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-14T21:15:10Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T18:00:00", - "duration": 10800000, - "percent": 1.45, - "rate": 1.66, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T18:00:00", - "duration": 10800000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-10-14T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T18:00:00", - "duration": 8110000, - "expectedDuration": 10800000, - "percent": 1.45, - "rate": 1.66, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T18:00:00", - "duration": 10800000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-10-14T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T20:15:10", - "duration": 6290000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T12:00:00", - "duration": 8739000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T14:25:39", - "duration": 1563000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T14:51:42", - "duration": 5877000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T16:29:39", - "duration": 10800000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T16:29:39", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-15T20:29:39Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T16:29:39", - "duration": 5421000, - "expectedDuration": 10800000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T16:29:39", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-15T20:29:39Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T18:00:00", - "duration": 10800000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T18:00:00", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-15T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T18:00:00", - "duration": 5379000, - "expectedDuration": 10800000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T18:00:00", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-15T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T19:29:39", - "duration": 9021000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T18:00:00", - "duration": 813000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T18:13:33", - "duration": 18000000, - "percent": 1.65, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T18:13:33", - "duration": 18000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-16T22:13:33Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T18:13:33", - "duration": 13587000, - "expectedDuration": 18000000, - "percent": 1.65, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T18:13:33", - "duration": 18000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-16T22:13:33Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T22:00:00", - "duration": 18000000, - "percent": 1.65, - "rate": 2.39, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T22:00:00", - "duration": 18000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-17T02:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T22:00:00", - "duration": 4413000, - "expectedDuration": 18000000, - "percent": 1.65, - "rate": 2.39, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T22:00:00", - "duration": 18000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-17T02:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T23:13:33", - "duration": 2787000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T12:00:00", - "duration": 12800000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T15:33:20", - "duration": 256000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T15:37:36", - "duration": 8544000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T00:00:00", - "duration": 586000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T00:09:46", - "duration": 12600000, - "percent": 1.7, - "rate": 2.8, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T00:09:46", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-19T04:09:46Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T00:09:46", - "duration": 12014000, - "expectedDuration": 12600000, - "percent": 1.7, - "rate": 2.8, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T00:09:46", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-19T04:09:46Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T03:30:00", - "duration": 12600000, - "percent": 1.7, - "rate": 2.63, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T03:30:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-10-19T07:30:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T03:30:00", - "duration": 586000, - "expectedDuration": 12600000, - "percent": 1.7, - "rate": 2.63, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T03:30:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-10-19T07:30:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T03:39:46", - "duration": 17414000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T12:00:00", - "duration": 17302000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T16:48:22", - "duration": 7200000, - "percent": 1.6, - "rate": 1.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T16:48:22", - "duration": 7200000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-19T20:48:22Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T16:48:22", - "duration": 4298000, - "expectedDuration": 7200000, - "percent": 1.6, - "rate": 1.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T16:48:22", - "duration": 7200000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-19T20:48:22Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T18:00:00", - "duration": 7200000, - "percent": 1.6, - "rate": 1.84, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T18:00:00", - "duration": 7200000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-19T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T18:00:00", - "duration": 2902000, - "expectedDuration": 7200000, - "percent": 1.6, - "rate": 1.84, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T18:00:00", - "duration": 7200000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-19T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T18:48:22", - "duration": 11498000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T12:00:00", - "duration": 19646000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T17:27:26", - "duration": 10800000, - "percent": 1.75, - "rate": 1.13, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T17:27:26", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-20T21:27:26Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T17:27:26", - "duration": 1954000, - "expectedDuration": 10800000, - "percent": 1.75, - "rate": 1.13, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T17:27:26", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-20T21:27:26Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T18:00:00", - "duration": 10800000, - "percent": 1.75, - "rate": 2.01, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T18:00:00", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-20T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T18:00:00", - "duration": 8846000, - "expectedDuration": 10800000, - "percent": 1.75, - "rate": 2.01, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T18:00:00", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-20T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T20:27:26", - "duration": 5554000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T22:00:00", - "duration": 3002000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T22:50:02", - "duration": 416000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T22:56:58", - "duration": 3782000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T12:00:00", - "duration": 11357000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T15:09:17", - "duration": 12600000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T15:09:17", - "duration": 12600000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-22T19:09:17Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T15:09:17", - "duration": 10243000, - "expectedDuration": 12600000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T15:09:17", - "duration": 12600000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-22T19:09:17Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T18:00:00", - "duration": 12600000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T18:00:00", - "duration": 12600000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-22T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T18:00:00", - "duration": 2357000, - "expectedDuration": 12600000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T18:00:00", - "duration": 12600000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-22T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T18:39:17", - "duration": 12043000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T08:30:00", - "duration": 9912000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T11:15:12", - "duration": 9000000, - "percent": 0.4, - "rate": 0.58, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T11:15:12", - "duration": 9000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-23T15:15:12Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T11:15:12", - "duration": 2688000, - "expectedDuration": 9000000, - "percent": 0.4, - "rate": 0.58, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T11:15:12", - "duration": 9000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-23T15:15:12Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T12:00:00", - "duration": 8340000, - "percent": 0.4, - "rate": 0.26, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T12:00:00", - "duration": 8340000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-23T16:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T12:00:00", - "duration": 5612000, - "expectedDuration": 8340000, - "percent": 0.4, - "rate": 0.26, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T12:00:00", - "duration": 8340000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-23T16:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T13:33:32", - "duration": 38000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T10:34:10", - "duration": 627000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T10:44:37", - "duration": 3600000, - "percent": 1.15, - "rate": 1.66, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T10:44:37", - "duration": 3600000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-10-23T17:44:37Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T11:44:37", - "duration": 923000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T18:00:00", - "duration": 10191000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T20:49:51", - "duration": 12600000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T20:49:51", - "duration": 12600000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-24T03:49:51Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T20:49:51", - "duration": 4209000, - "expectedDuration": 12600000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T20:49:51", - "duration": 12600000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-24T03:49:51Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T22:00:00", - "duration": 12600000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T22:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-24T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T22:00:00", - "duration": 7200000, - "expectedDuration": 12600000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T22:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-24T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T00:00:00", - "duration": 12600000, - "percent": 1.4, - "rate": 2.31, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-24T07:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T00:00:00", - "duration": 1191000, - "expectedDuration": 12600000, - "percent": 1.4, - "rate": 2.31, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-24T07:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T00:19:51", - "duration": 11409000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T03:30:00", - "duration": 2088000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T04:04:48", - "duration": 20248000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T09:42:16", - "duration": 8264000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T12:00:00", - "duration": 7234000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T14:00:34", - "duration": 5400000, - "percent": 1.6, - "rate": 1.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T14:00:34", - "duration": 5400000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-25T21:00:34Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T15:30:34", - "duration": 8966000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T03:30:00", - "duration": 16729000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:08:49", - "duration": 7200000, - "percent": 1.5, - "rate": 2.32, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:08:49", - "duration": 7200000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-10-27T15:08:49Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:08:49", - "duration": 1271000, - "expectedDuration": 7200000, - "percent": 1.5, - "rate": 2.32, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:08:49", - "duration": 7200000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-10-27T15:08:49Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:30:00", - "duration": 7200000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-27T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:30:00", - "duration": 5929000, - "expectedDuration": 7200000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-27T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T10:08:49", - "duration": 6671000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T12:00:00", - "duration": 65000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T12:01:05", - "duration": 421000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T12:08:06", - "duration": 21114000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T18:00:00", - "duration": 4889000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T19:21:29", - "duration": 14570000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T23:24:19", - "duration": 2141000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T03:30:00", - "duration": 13402000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T07:13:22", - "duration": 17773000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T12:09:35", - "duration": 5452000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T13:40:27", - "duration": 9000000, - "percent": 1.5, - "rate": 0.97, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T13:40:27", - "duration": 9000000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-11-03T20:40:27Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T16:10:27", - "duration": 6573000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T03:30:00", - "duration": 6646000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T05:20:46", - "duration": 81000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T04:22:07", - "duration": 14873000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T18:00:00", - "duration": 3581000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "annotations": [{ "code": "basal/unknown-duration" }], - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T18:59:41", - "duration": 0 - } -] -` - -func GetJFBasalData() []map[string]interface{} { - data := []map[string]interface{}{} - json.Unmarshal([]byte(jfBasalStr), &data) - return data -} - -var platformBasalStr = `[ - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T22:00:00", - "duration": 1217000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T22:20:17", - "duration": 800000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T22:33:37", - "duration": 5183000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T00:00:00", - "duration": 7992000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T02:13:12", - "duration": 2334000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T05:52:06", - "duration": 6987000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T07:48:33", - "duration": 1140000, - "percent": 0.4, - "rate": 0.62, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T08:07:02", - "duration": 2631000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T08:50:53", - "duration": 8779000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:17:12", - "duration": 1800000, - "percent": 0.6, - "rate": 0.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:47:12", - "duration": 592000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:57:04", - "duration": 7200000, - "percent": 0.35, - "rate": 0.5, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.43, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T12:00:00", - "duration": 7200000, - "percent": 0.35, - "rate": 0.22, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.63, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T13:57:04", - "duration": 14576000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T08:30:00", - "duration": 3356000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T09:25:56", - "duration": 7200000, - "percent": 0.5, - "rate": 0.72, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T11:25:56", - "duration": 2044000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T12:00:00", - "duration": 1425000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T12:23:45", - "duration": 5400000, - "percent": 0.5, - "rate": 0.32, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T13:53:45", - "duration": 14775000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T00:00:00", - "duration": 2543000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T00:42:23", - "duration": 12600000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T03:30:00", - "duration": 12600000, - "percent": 0.65, - "rate": 0.84, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.29, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T04:12:23", - "duration": 4657000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T08:30:00", - "duration": 10937000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T11:32:17", - "duration": 10800000, - "percent": 0.6, - "rate": 0.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T12:00:00", - "duration": 7860000, - "percent": 0.6, - "rate": 0.39, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T13:42:37", - "duration": 47000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T13:43:24", - "duration": 10800000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T16:43:24", - "duration": 4596000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T18:00:00", - "duration": 2896000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T18:48:16", - "duration": 4862000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T20:09:18", - "duration": 6642000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T00:00:00", - "duration": 10582000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T02:56:22", - "duration": 21600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T03:30:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T05:30:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T08:30:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T08:56:22", - "duration": 11018000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T12:00:00", - "duration": 7848000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T14:10:48", - "duration": 9000000, - "percent": 1.25, - "rate": 0.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T16:40:48", - "duration": 4752000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T18:00:00", - "duration": 4786000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T19:19:46", - "duration": 492000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T19:27:58", - "duration": 9122000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T08:30:00", - "duration": 5770000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:06:10", - "duration": 1860000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:36:13", - "duration": 13000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:36:26", - "duration": 3600000, - "percent": 1.15, - "rate": 1.66, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T11:36:26", - "duration": 1414000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T12:00:00", - "duration": 19357000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T17:22:37", - "duration": 385000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T17:29:02", - "duration": 1858000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T12:00:00", - "duration": 499000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T12:08:19", - "duration": 9000000, - "percent": 0.55, - "rate": 0.35, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T14:38:19", - "duration": 8117000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T16:53:36", - "duration": 5400000, - "percent": 1.5, - "rate": 0.97, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T18:00:00", - "duration": 5400000, - "percent": 1.5, - "rate": 1.72, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T18:23:36", - "duration": 12984000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T22:00:00", - "duration": 1335000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T22:22:15", - "duration": 7200000, - "percent": 0.7, - "rate": 0.91, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T00:00:00", - "duration": 7200000, - "percent": 0.7, - "rate": 1.01, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T00:22:15", - "duration": 5651000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T01:56:26", - "duration": 16200000, - "percent": 0.5, - "rate": 0.72, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:30:00", - "duration": 6360000, - "percent": 0.5, - "rate": 0.65, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:41:53", - "duration": 14000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:42:07", - "duration": 480000, - "percent": 0.15000000000000002, - "rate": 0.19, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.27, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:49:40", - "duration": 21000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:50:01", - "duration": 1260000, - "rate": 0 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T04:10:44", - "duration": 17000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T04:11:01", - "duration": 25200000, - "percent": 0.30000000000000004, - "rate": 0.39, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T05:30:00", - "duration": 25200000, - "percent": 0.30000000000000004, - "rate": 0.46, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.53, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T08:30:00", - "duration": 21000000, - "percent": 0.30000000000000004, - "rate": 0.43, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.43, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T10:00:43", - "duration": 7157000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T08:30:00", - "duration": 7831000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T10:40:31", - "duration": 3660000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T11:41:01", - "duration": 26048000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T18:55:09", - "duration": 11091000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T08:30:00", - "duration": 4143000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T09:39:03", - "duration": 5400000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T11:09:03", - "duration": 3057000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T12:00:00", - "duration": 11173000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T15:06:13", - "duration": 10800000, - "percent": 0.5, - "rate": 0.32, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T18:00:00", - "duration": 10800000, - "percent": 0.5, - "rate": 0.57, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.14, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T18:06:13", - "duration": 14027000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T05:30:00", - "duration": 7330000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T07:32:10", - "duration": 8320000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T09:50:50", - "duration": 7750000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T12:00:00", - "duration": 13768000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T15:49:28", - "duration": 1919000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T13:21:27", - "duration": 16713000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T18:00:00", - "duration": 7752000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T20:09:12", - "duration": 4951000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T21:31:43", - "duration": 1697000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T05:30:00", - "duration": 2075000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T06:04:35", - "duration": 5400000, - "percent": 1.4, - "rate": 2.17, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T07:34:35", - "duration": 3325000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T08:30:00", - "duration": 6166000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T10:12:46", - "duration": 5400000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T11:42:46", - "duration": 1034000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T22:00:00", - "duration": 4345000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T23:12:25", - "duration": 1767000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T23:41:52", - "duration": 1088000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T05:30:00", - "duration": 7632000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T07:37:12", - "duration": 7359000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T09:39:51", - "duration": 8409000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T08:30:00", - "duration": 7692000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T10:38:12", - "duration": 1864000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T11:09:16", - "duration": 3044000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T18:00:00", - "duration": 11017000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T21:03:37", - "duration": 10800000, - "percent": 1.5, - "rate": 1.72, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T22:00:00", - "duration": 10800000, - "percent": 1.5, - "rate": 1.95, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T00:00:00", - "duration": 10800000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T00:03:37", - "duration": 12383000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T05:30:00", - "duration": 5676000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T07:04:36", - "duration": 7200000, - "percent": 0.4, - "rate": 0.62, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T08:30:00", - "duration": 7200000, - "percent": 0.4, - "rate": 0.58, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T09:04:36", - "duration": 8062000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T11:18:58", - "duration": 3600000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T12:00:00", - "duration": 3600000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T12:18:58", - "duration": 20462000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T18:00:00", - "duration": 3789000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T19:03:09", - "duration": 4406000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T20:16:35", - "duration": 6205000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T12:00:00", - "duration": 21479000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T17:57:59", - "duration": 7200000, - "percent": 1.45, - "rate": 0.94, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T18:00:00", - "duration": 7200000, - "percent": 1.45, - "rate": 1.66, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.14, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T19:57:59", - "duration": 7321000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T03:30:00", - "duration": 6942000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:25:42", - "duration": 5400000, - "percent": 1.5, - "rate": 1.95, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:30:00", - "duration": 5400000, - "percent": 1.5, - "rate": 2.32, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T06:55:42", - "duration": 5658000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T18:00:00", - "duration": 12497000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T21:28:17", - "duration": 2135000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T22:03:52", - "duration": 6968000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T00:00:00", - "duration": 4032000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T01:07:12", - "duration": 7200000, - "percent": 1.75, - "rate": 2.53, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T03:07:12", - "duration": 1368000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T22:00:00", - "duration": 4835000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T23:20:35", - "duration": 5400000, - "percent": 1.5, - "rate": 1.95, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T00:00:00", - "duration": 5400000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T00:50:35", - "duration": 9565000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T05:30:00", - "duration": 1701000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T05:58:21", - "duration": 50296000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T19:56:37", - "duration": 7403000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T18:00:00", - "duration": 8649000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T20:24:09", - "duration": 9000000, - "percent": 1.95, - "rate": 2.24, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T22:00:00", - "duration": 9000000, - "percent": 1.95, - "rate": 2.53, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T22:54:09", - "duration": 3951000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T18:00:00", - "duration": 366000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T18:06:06", - "duration": 613000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T18:16:19", - "duration": 13421000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T03:30:00", - "duration": 5480000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:01:20", - "duration": 12600000, - "percent": 1.6, - "rate": 2.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:30:00", - "duration": 12600000, - "percent": 1.6, - "rate": 2.48, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T08:30:00", - "duration": 12600000, - "percent": 1.6, - "rate": 2.32, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T08:31:20", - "duration": 12520000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T05:30:00", - "duration": 3692000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T06:31:32", - "duration": 14400000, - "percent": 1.65, - "rate": 2.55, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T08:30:00", - "duration": 14400000, - "percent": 1.65, - "rate": 2.39, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T10:31:32", - "duration": 5308000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T18:00:00", - "duration": 9007000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T20:30:07", - "duration": 4826000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T21:50:33", - "duration": 567000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T12:00:00", - "duration": 175000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T12:02:55", - "duration": 203000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T12:06:18", - "duration": 21222000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T22:00:00", - "duration": 5252000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T23:27:32", - "duration": 7200000, - "percent": 1.45, - "rate": 1.88, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T00:00:00", - "duration": 7200000, - "percent": 1.45, - "rate": 2.1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T01:27:32", - "duration": 7348000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T05:30:00", - "duration": 10163000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T08:19:23", - "duration": 227000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T08:23:10", - "duration": 410000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T08:30:00", - "duration": 1916000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T09:01:56", - "duration": 291000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T09:06:47", - "duration": 10393000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T00:00:00", - "duration": 2058000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T00:34:18", - "duration": 18000000, - "percent": 1.3, - "rate": 1.88, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T03:30:00", - "duration": 18000000, - "percent": 1.3, - "rate": 1.69, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T05:30:00", - "duration": 18000000, - "percent": 1.3, - "rate": 2.01, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T05:34:18", - "duration": 10542000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T00:00:00", - "duration": 5352000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T01:29:12", - "duration": 16200000, - "percent": 1.45, - "rate": 2.1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T03:30:00", - "duration": 16200000, - "percent": 1.45, - "rate": 1.88, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T05:30:00", - "duration": 16200000, - "percent": 1.45, - "rate": 2.24, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T05:59:12", - "duration": 9048000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T08:30:00", - "duration": 10301000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T11:21:41", - "duration": 1674000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T11:49:35", - "duration": 625000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T12:00:00", - "duration": 10354000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T14:52:34", - "duration": 729000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T15:04:43", - "duration": 10517000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T05:30:00", - "duration": 6107000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T07:11:47", - "duration": 3600000, - "percent": 0.35, - "rate": 0.54, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T08:11:47", - "duration": 1093000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T08:30:00", - "duration": 5259000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T09:57:39", - "duration": 54000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T09:58:33", - "duration": 7287000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T22:00:00", - "duration": 4793000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T23:19:53", - "duration": 5171000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T00:46:04", - "duration": 9836000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T12:00:00", - "duration": 19060000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T17:17:40", - "duration": 298000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T17:22:38", - "duration": 2242000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T18:00:00", - "duration": 762000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T18:12:42", - "duration": 364000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T18:18:46", - "duration": 13274000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T08:30:00", - "duration": 3806000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T09:33:26", - "duration": 32400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T12:00:00", - "duration": 32400000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T18:00:00", - "duration": 32400000, - "percent": 0.75, - "rate": 0.86, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T18:33:26", - "duration": 12394000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T08:30:00", - "duration": 12207000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T11:53:27", - "duration": 10800000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T12:00:00", - "duration": 10800000, - "percent": 0.65, - "rate": 0.42, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T14:53:27", - "duration": 11193000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T00:00:00", - "duration": 4261000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T01:11:01", - "duration": 404000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T01:17:45", - "duration": 7935000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T08:30:00", - "duration": 1757000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T08:59:17", - "duration": 695000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T09:10:52", - "duration": 10148000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T12:00:00", - "duration": 18043000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T17:00:43", - "duration": 2404000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T17:40:47", - "duration": 1153000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T00:00:00", - "duration": 4572000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T01:16:12", - "duration": 303000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T01:21:15", - "duration": 7725000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T08:30:00", - "duration": 1219000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T08:50:19", - "duration": 5400000, - "percent": 1.3, - "rate": 1.88, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T10:20:19", - "duration": 5981000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T12:00:00", - "duration": 14758000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T16:05:58", - "duration": 375000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T16:12:13", - "duration": 6467000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T18:00:00", - "duration": 11599000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T21:13:19", - "duration": 711000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T21:25:10", - "duration": 2090000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T18:00:00", - "duration": 10305000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T20:51:45", - "duration": 7200000, - "percent": 0.19999999999999996, - "rate": 0.23, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T22:00:00", - "duration": 7200000, - "percent": 0.19999999999999996, - "rate": 0.28, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T22:51:45", - "duration": 4095000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T12:00:00", - "duration": 19370000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T17:22:50", - "duration": 3600000, - "percent": 0.7, - "rate": 0.45, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T18:00:00", - "duration": 3600000, - "percent": 0.7, - "rate": 0.8, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.14, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T18:22:50", - "duration": 13030000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T03:30:00", - "duration": 7580000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T05:36:20", - "duration": 249000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T05:40:29", - "duration": 10171000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T08:30:00", - "duration": 169000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T08:32:49", - "duration": 544000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T08:41:53", - "duration": 11887000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T12:00:00", - "duration": 16275000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T16:31:15", - "duration": 455000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T16:38:50", - "duration": 4870000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T18:00:00", - "duration": 13413000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T21:43:33", - "duration": 246000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T21:47:39", - "duration": 741000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:00:00", - "duration": 643000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:10:43", - "duration": 60000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:10:50", - "duration": 273000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:15:23", - "duration": 28000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:15:51", - "duration": 7200000, - "percent": 1.3, - "rate": 1.95, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T02:15:51", - "duration": 4449000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T00:00:00", - "duration": 10840000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:00:40", - "duration": 10800000, - "percent": 1.45, - "rate": 2.17, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:30:00", - "duration": 10800000, - "percent": 1.45, - "rate": 1.95, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.34, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T05:30:00", - "duration": 10800000, - "percent": 1.45, - "rate": 2.24, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T06:00:40", - "duration": 8960000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T05:30:00", - "duration": 9662000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T08:11:02", - "duration": 6831000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T10:04:53", - "duration": 973000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T10:21:06", - "duration": 97000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T10:22:43", - "duration": 5837000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T12:00:00", - "duration": 4664000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T13:17:44", - "duration": 7380000, - "percent": 1.5, - "rate": 0.97, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T15:19:49", - "duration": 9611000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T22:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T22:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T22:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T05:30:00", - "duration": 7957000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T07:42:37", - "duration": 35000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T07:43:12", - "duration": 2808000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T08:30:00", - "duration": 8781000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T10:56:21", - "duration": 254000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T11:00:35", - "duration": 3565000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T00:00:00", - "duration": 4542000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T01:15:42", - "duration": 10800000, - "percent": 0.7, - "rate": 1.05, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T03:30:00", - "duration": 10800000, - "percent": 0.7, - "rate": 0.94, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.34, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T04:15:42", - "duration": 4458000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T18:00:00", - "duration": 366000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T18:06:06", - "duration": 21600000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T22:00:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T00:00:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T00:06:06", - "duration": 9204000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T02:39:30", - "duration": 18000000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T03:30:00", - "duration": 18000000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.35, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T05:30:00", - "duration": 18000000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T07:39:30", - "duration": 3030000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T08:30:00", - "duration": 8164000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T10:46:04", - "duration": 18000000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T12:00:00", - "duration": 18000000, - "percent": 0.65, - "rate": 0.42, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T15:46:04", - "duration": 8036000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T12:00:00", - "duration": 21410000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T17:56:50", - "duration": 2163000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T18:32:53", - "duration": 12427000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T22:00:00", - "duration": 5415000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T23:30:15", - "duration": 7200000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T00:00:00", - "duration": 7200000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T01:30:15", - "duration": 7185000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T08:30:00", - "duration": 345000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T08:35:45", - "duration": 5400000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T10:05:45", - "duration": 6855000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T18:00:00", - "duration": 9705000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T20:41:45", - "duration": 7200000, - "percent": 1.3, - "rate": 1.49, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T22:00:00", - "duration": 7200000, - "percent": 1.3, - "rate": 1.88, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T22:41:45", - "duration": 4695000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T00:00:00", - "duration": 5211000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T01:26:51", - "duration": 199000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T01:30:10", - "duration": 147000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T01:32:37", - "duration": 12600000, - "percent": 0.75, - "rate": 1.12, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.49, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T03:30:00", - "duration": 12600000, - "percent": 0.75, - "rate": 1.01, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.35, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T05:02:37", - "duration": 1643000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T12:00:00", - "duration": 91000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T12:01:31", - "duration": 7200000, - "percent": 1.35, - "rate": 0.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T14:01:31", - "duration": 14309000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T00:00:00", - "duration": 8771000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T02:26:11", - "duration": 272000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T02:30:43", - "duration": 3557000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T08:30:00", - "duration": 5906000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T10:08:26", - "duration": 2274000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T10:46:20", - "duration": 4420000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T18:00:00", - "duration": 2434000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T18:40:34", - "duration": 3332000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T19:36:06", - "duration": 8634000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T22:00:00", - "duration": 7042000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T23:57:22", - "duration": 114000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T23:59:16", - "duration": 44000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T08:30:00", - "duration": 135000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T08:32:15", - "duration": 360000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T09:38:15", - "duration": 8505000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T00:00:00", - "duration": 5721000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T01:35:21", - "duration": 660000, - "percent": 0.6, - "rate": 0.9, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T01:45:59", - "duration": 6241000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T18:00:00", - "duration": 12763000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T21:32:43", - "duration": 200000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T21:36:03", - "duration": 1437000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T00:00:00", - "duration": 7717000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T02:08:37", - "duration": 9000000, - "percent": 1.2, - "rate": 1.8, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T03:30:00", - "duration": 9000000, - "percent": 1.2, - "rate": 1.62, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.35, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T04:38:37", - "duration": 3083000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T00:00:00", - "duration": 1387000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T00:23:07", - "duration": 5575000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T01:56:02", - "duration": 5638000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T00:00:00", - "duration": 5074000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T01:24:34", - "duration": 3600000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T02:24:34", - "duration": 3926000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T12:00:00", - "duration": 14636000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T16:03:56", - "duration": 156000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T16:06:32", - "duration": 6808000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T12:00:00", - "duration": 261000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T12:04:21", - "duration": 241000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T12:08:22", - "duration": 21098000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T08:30:00", - "duration": 5750000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T10:05:50", - "duration": 188000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T10:08:58", - "duration": 6662000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T12:00:00", - "duration": 17191000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T16:46:31", - "duration": 4727000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T18:05:18", - "duration": 14082000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T18:00:00", - "duration": 2581000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T18:43:01", - "duration": 67000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T21:44:08", - "duration": 952000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T18:00:00", - "duration": 9738000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T20:42:18", - "duration": 1004000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T20:59:02", - "duration": 3658000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T00:00:00", - "duration": 12403000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:26:43", - "duration": 7200000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:30:00", - "duration": 7200000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.35, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T05:26:43", - "duration": 197000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T18:00:00", - "duration": 3804000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T19:03:24", - "duration": 476000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T19:11:20", - "duration": 10120000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T08:30:00", - "duration": 3078000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T09:21:18", - "duration": 5400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T10:51:18", - "duration": 4122000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T18:00:00", - "duration": 8562000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T20:22:42", - "duration": 87000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T17:24:09", - "duration": 2151000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T18:00:00", - "duration": 10423000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T20:53:43", - "duration": 2326000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T21:32:29", - "duration": 1651000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T08:30:00", - "duration": 11164000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T11:36:04", - "duration": 7381000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T13:39:05", - "duration": 15655000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T18:00:00", - "duration": 6679000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T19:51:19", - "duration": 1653000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T20:18:52", - "duration": 6068000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T08:30:00", - "duration": 6131000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T10:12:11", - "duration": 1800000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T10:42:11", - "duration": 4669000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T12:00:00", - "duration": 243000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T12:04:03", - "duration": 36000000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T18:00:00", - "duration": 36000000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T22:00:00", - "duration": 36000000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T22:04:02", - "duration": 6958000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T08:30:00", - "duration": 321000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T08:35:21", - "duration": 28800000, - "percent": 0.7, - "rate": 1.01, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T12:00:00", - "duration": 28200000, - "percent": 0.7, - "rate": 0.45, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T16:25:06", - "duration": 17000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T16:25:23", - "duration": 12600000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T18:00:00", - "duration": 12600000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T19:55:23", - "duration": 7477000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T22:00:00", - "duration": 5512000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T23:31:52", - "duration": 351000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T23:37:43", - "duration": 562000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T23:47:05", - "duration": 36000000, - "percent": 0.6, - "rate": 0.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:00:00", - "duration": 840000, - "percent": 0.6, - "rate": 0.9, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:01:02", - "duration": 13000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:01:15", - "duration": 10380000, - "percent": 0.5, - "rate": 0.75, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T02:54:02", - "duration": 17000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T02:54:19", - "duration": 27000000, - "percent": 0.35, - "rate": 0.52, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.49, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T03:30:00", - "duration": 27000000, - "percent": 0.35, - "rate": 0.47, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.34, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T05:30:00", - "duration": 14700000, - "percent": 0.35, - "rate": 0.54, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T06:59:14", - "duration": 5446000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T08:30:00", - "duration": 1684000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T08:58:04", - "duration": 3600000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T09:58:04", - "duration": 211000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T10:01:35", - "duration": 3600000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T11:01:35", - "duration": 3505000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T12:00:00", - "duration": 1514000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T12:25:14", - "duration": 12840000, - "percent": 0.55, - "rate": 0.35, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T15:58:44", - "duration": 8000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T15:58:52", - "duration": 5400000, - "percent": 1.25, - "rate": 0.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T17:28:52", - "duration": 1868000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T18:00:00", - "duration": 4291000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T19:11:31", - "duration": 60000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T19:12:19", - "duration": 10061000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T00:00:00", - "duration": 2499000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T00:41:39", - "duration": 7200000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T02:41:39", - "duration": 2901000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T05:30:00", - "duration": 10759000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T08:29:19", - "duration": 4125000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T09:38:04", - "duration": 8516000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T12:00:00", - "duration": 4493000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T13:14:53", - "duration": 3600000, - "percent": 0.9, - "rate": 0.58, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T14:14:53", - "duration": 13507000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T05:30:00", - "duration": 8560000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T07:52:40", - "duration": 8961000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T10:22:01", - "duration": 5879000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T22:00:00", - "duration": 6208000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T23:43:28", - "duration": 7200000, - "percent": 1.1, - "rate": 1.59, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T00:00:00", - "duration": 7200000, - "percent": 1.1, - "rate": 1.65, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T01:43:28", - "duration": 6392000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T12:00:00", - "duration": 11187000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T15:06:27", - "duration": 3600000, - "percent": 0.7, - "rate": 0.45, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T16:06:27", - "duration": 6813000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T08:30:00", - "duration": 7374000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T10:32:54", - "duration": 790000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T10:46:04", - "duration": 4436000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T05:30:00", - "duration": 10425000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T08:23:45", - "duration": 375000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T12:00:00", - "duration": 10788000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T14:59:48", - "duration": 3678000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T16:01:06", - "duration": 7134000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T12:00:00", - "duration": 9679000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T14:41:19", - "duration": 10800000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T17:41:19", - "duration": 1121000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T22:00:00", - "duration": 4227000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T23:10:27", - "duration": 586000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T23:20:13", - "duration": 2387000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T18:00:00", - "duration": 13412000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T21:43:32", - "duration": 200000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T21:46:52", - "duration": 788000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T00:00:00", - "duration": 3746000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:02:26", - "duration": 180000, - "percent": 0.7, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:04:34", - "duration": 11000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:04:45", - "duration": 18000000, - "percent": 0.85, - "rate": 1.31, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T03:30:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.19, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T05:30:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.36, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T06:04:45", - "duration": 8715000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T00:00:00", - "duration": 10498000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T02:54:58", - "duration": 21600000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T03:30:00", - "duration": 21600000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T05:30:00", - "duration": 21600000, - "percent": 0.75, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T08:30:00", - "duration": 21600000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T08:54:58", - "duration": 11102000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T22:00:00", - "duration": 4513000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T23:15:13", - "duration": 147000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T23:17:40", - "duration": 2540000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T00:00:00", - "duration": 635000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T00:10:35", - "duration": 315000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T00:15:50", - "duration": 11650000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T18:00:00", - "duration": 1631000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T18:27:11", - "duration": 3420000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T19:24:10", - "duration": 9350000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T05:30:00", - "duration": 3903000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T06:35:03", - "duration": 7200000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T08:30:00", - "duration": 7200000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T08:35:03", - "duration": 2092000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T09:09:55", - "duration": 43200000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T12:00:00", - "duration": 16200000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T13:39:54", - "duration": 221000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T13:43:35", - "duration": 10550000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T16:39:25", - "duration": 21498000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T22:37:43", - "duration": 4937000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T00:00:00", - "duration": 5097000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T01:24:57", - "duration": 30600000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T03:30:00", - "duration": 30600000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.35, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T05:30:00", - "duration": 30600000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T08:30:00", - "duration": 30600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T09:54:57", - "duration": 4178000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T11:04:35", - "duration": 41400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T12:00:00", - "duration": 41400000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T18:00:00", - "duration": 41400000, - "percent": 0.75, - "rate": 0.86, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T22:00:00", - "duration": 41400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T22:34:35", - "duration": 5125000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T00:00:00", - "duration": 4232000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T01:10:32", - "duration": 28800000, - "percent": 0.75, - "rate": 1.12, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.49, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T03:30:00", - "duration": 28800000, - "percent": 0.75, - "rate": 1.01, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.35, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T05:30:00", - "duration": 28800000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T08:30:00", - "duration": 28800000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T09:10:32", - "duration": 10168000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T05:30:00", - "duration": 10250000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:20:50", - "duration": 28800000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:30:00", - "duration": 28800000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T12:00:00", - "duration": 28800000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T16:20:50", - "duration": 5950000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T18:00:00", - "duration": 9910000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T20:45:10", - "duration": 257000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T20:49:27", - "duration": 4233000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T03:30:00", - "duration": 4311000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T04:41:51", - "duration": 18428000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T09:48:59", - "duration": 7861000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T18:00:00", - "duration": 11857000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T21:17:37", - "duration": 10800000, - "percent": 1.15, - "rate": 1.32, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T22:00:00", - "duration": 5460000, - "percent": 1.15, - "rate": 1.66, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T22:48:11", - "duration": 2421000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T23:28:32", - "duration": 3600000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T00:00:00", - "duration": 3600000, - "percent": 1.25, - "rate": 1.93, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T00:28:32", - "duration": 10888000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T12:00:00", - "duration": 21052000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T17:50:52", - "duration": 10800000, - "percent": 1.25, - "rate": 0.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T18:00:00", - "duration": 10800000, - "percent": 1.25, - "rate": 1.43, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.14, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T20:50:52", - "duration": 4148000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T05:30:00", - "duration": 1821000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T06:00:21", - "duration": 217000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T06:03:58", - "duration": 8762000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T18:00:00", - "duration": 2689000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T18:44:49", - "duration": 3986000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T19:51:15", - "duration": 7725000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T18:00:00", - "duration": 8609000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T20:23:29", - "duration": 9000000, - "percent": 1.5, - "rate": 1.72, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T22:00:00", - "duration": 7140000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T22:21:32", - "duration": 5908000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T12:00:00", - "duration": 16133000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T16:28:53", - "duration": 113000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T16:30:46", - "duration": 5354000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T12:00:00", - "duration": 19563000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T17:26:03", - "duration": 368000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T17:32:11", - "duration": 1669000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T22:00:00", - "duration": 1859000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T22:30:59", - "duration": 3600000, - "percent": 1.95, - "rate": 2.82, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T23:30:59", - "duration": 1741000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T08:30:00", - "duration": 8897000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T10:58:17", - "duration": 1755000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T11:27:32", - "duration": 1948000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T12:00:00", - "duration": 19655000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T17:27:35", - "duration": 375000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T17:33:50", - "duration": 1570000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T18:00:00", - "duration": 13374000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T21:42:54", - "duration": 10800000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T22:00:00", - "duration": 10800000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T00:00:00", - "duration": 10800000, - "percent": 1.4, - "rate": 2.1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T00:42:54", - "duration": 10026000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T08:30:00", - "duration": 11426000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T11:40:26", - "duration": 7949000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T13:52:55", - "duration": 14825000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T08:30:00", - "duration": 2522000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T09:12:02", - "duration": 14514000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T13:13:56", - "duration": 17164000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T18:00:00", - "duration": 14339000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T21:58:59", - "duration": 1800000, - "percent": 0.09999999999999998, - "rate": 0.11, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.1, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T22:00:00", - "duration": 1800000, - "percent": 0.09999999999999998, - "rate": 0.14, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T22:28:59", - "duration": 5461000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T12:00:00", - "duration": 20380000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T17:39:40", - "duration": 3600000, - "percent": 0.65, - "rate": 0.42, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T18:00:00", - "duration": 3600000, - "percent": 0.65, - "rate": 0.74, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.14, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T18:39:40", - "duration": 12020000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T22:00:00", - "duration": 1941000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T22:32:21", - "duration": 332000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T22:37:53", - "duration": 4927000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T00:00:00", - "duration": 7844000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T02:10:44", - "duration": 5400000, - "percent": 0.6, - "rate": 0.9, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T03:30:00", - "duration": 5400000, - "percent": 0.6, - "rate": 0.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.35, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T03:40:44", - "duration": 6556000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T22:00:00", - "duration": 89000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T22:01:29", - "duration": 427000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T22:08:36", - "duration": 6684000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T12:00:00", - "duration": 6521000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:48:41", - "duration": 180000, - "percent": 0.6, - "rate": 0.39, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:51:15", - "duration": 329000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:56:44", - "duration": 5400000, - "percent": 1.2, - "rate": 0.78, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T15:26:44", - "duration": 9196000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T00:00:00", - "duration": 2718000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T00:45:18", - "duration": 410000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T00:52:08", - "duration": 9472000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T18:00:00", - "duration": 9098000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T20:31:38", - "duration": 238000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T20:35:36", - "duration": 5064000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T12:00:00", - "duration": 6090000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T13:41:30", - "duration": 277000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T13:46:07", - "duration": 8525000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-07T15:08:12", - "duration": 13000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T16:08:25", - "duration": 10295000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-07T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T12:00:00", - "duration": 537000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T12:08:57", - "duration": 190000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T12:12:07", - "duration": 20873000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T12:00:00", - "duration": 3798000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T13:03:18", - "duration": 482000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T14:12:18", - "duration": 13662000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T03:30:00", - "duration": 3971000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T04:36:11", - "duration": 250000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T04:40:21", - "duration": 2979000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T22:00:00", - "duration": 3091000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T22:51:31", - "duration": 1929000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T23:23:40", - "duration": 2180000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T12:00:00", - "duration": 2125000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T12:35:25", - "duration": 1737000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T13:04:22", - "duration": 17738000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T00:00:00", - "duration": 1723000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T00:28:43", - "duration": 27000000, - "percent": 0.65, - "rate": 0.97, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.49, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T03:30:00", - "duration": 27000000, - "percent": 0.65, - "rate": 0.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.34, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T05:30:00", - "duration": 27000000, - "percent": 0.65, - "rate": 1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T07:58:43", - "duration": 1877000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T12:00:00", - "duration": 11186000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T15:06:26", - "duration": 10709000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T18:04:55", - "duration": 14105000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T08:30:00", - "duration": 7555000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T10:35:55", - "duration": 27000000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T12:00:00", - "duration": 27000000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T18:00:00", - "duration": 27000000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T18:05:54", - "duration": 6111000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T19:47:45", - "duration": 18000000, - "percent": 0.85, - "rate": 0.97, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.14, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T22:00:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.23, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T00:00:00", - "duration": 17880000, - "percent": 0.85, - "rate": 1.27, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.49, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T00:44:56", - "duration": 112000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T00:46:48", - "duration": 9792000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T18:00:00", - "duration": 10769000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T20:59:29", - "duration": 3631000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T08:30:00", - "duration": 10621000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T11:27:01", - "duration": 25200000, - "percent": 0.8, - "rate": 1.12, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T12:00:00", - "duration": 14160000, - "percent": 0.8, - "rate": 0.48, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T15:22:15", - "duration": 52000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T18:23:07", - "duration": 13013000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T22:00:00", - "duration": 6238000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T23:43:58", - "duration": 870000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T23:58:28", - "duration": 92000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T00:00:00", - "duration": 9249000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T02:34:09", - "duration": 9000000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T03:30:00", - "duration": 9000000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.35, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T05:04:09", - "duration": 1551000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T08:30:00", - "duration": 6845000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T10:24:05", - "duration": 10800000, - "percent": 1.35, - "rate": 1.89, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T12:00:00", - "duration": 10800000, - "percent": 1.35, - "rate": 0.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T13:24:05", - "duration": 16555000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T05:30:00", - "duration": 8167000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T07:46:07", - "duration": 5319000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T09:14:46", - "duration": 9914000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T22:00:00", - "duration": 2939000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T22:48:59", - "duration": 3600000, - "percent": 0.85, - "rate": 1.19, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T23:48:59", - "duration": 661000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T00:00:00", - "duration": 10930000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T03:02:10", - "duration": 56000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T00:03:06", - "duration": 12414000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T12:00:00", - "duration": 16156000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T16:29:16", - "duration": 5400000, - "percent": 1.4, - "rate": 0.84, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T17:59:16", - "duration": 44000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T12:00:00", - "duration": 7901000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T14:11:41", - "duration": 1866000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T14:42:47", - "duration": 11833000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T08:30:00", - "duration": 7554000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T10:35:54", - "duration": 27000000, - "percent": 0.85, - "rate": 1.19, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T12:00:00", - "duration": 27000000, - "percent": 0.85, - "rate": 0.51, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T18:00:00", - "duration": 27000000, - "percent": 0.85, - "rate": 0.89, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T18:05:54", - "duration": 14046000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T22:00:00", - "duration": 5283000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T23:28:03", - "duration": 3855000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T00:32:18", - "duration": 10662000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T18:00:00", - "duration": 6951000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T19:55:51", - "duration": 7449000, - "rate": 1, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T22:00:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T05:30:00", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T08:30:00", - "duration": 10564000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T11:26:04", - "duration": 139000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T11:28:23", - "duration": 1897000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T00:00:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T03:30:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T00:00:00", - "duration": 11060000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:04:20", - "duration": 21600000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:30:00", - "duration": 21600000, - "percent": 0.75, - "rate": 0.93, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.24, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T05:30:00", - "duration": 19560000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T08:27:11", - "duration": 10538000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T11:22:49", - "duration": 2231000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T00:00:00", - "duration": 10459000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T02:54:19", - "duration": 7200000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T03:30:00", - "duration": 7200000, - "percent": 0.75, - "rate": 0.93, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.24, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T04:54:19", - "duration": 2141000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T00:00:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T03:30:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T00:00:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T03:30:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T18:00:00", - "duration": 4501000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T19:15:01", - "duration": 442000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T19:22:23", - "duration": 9457000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T00:00:00", - "duration": 9207000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T02:33:27", - "duration": 3600000, - "percent": 1.35, - "rate": 1.89, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T03:30:00", - "duration": 3600000, - "percent": 1.35, - "rate": 1.68, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.24, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T03:33:27", - "duration": 6993000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T00:00:00", - "duration": 7931000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T02:12:11", - "duration": 1802000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T02:42:13", - "duration": 2867000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T00:00:00", - "duration": 1644000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T00:27:24", - "duration": 387000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T00:33:51", - "duration": 10569000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T05:30:00", - "duration": 11850000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T08:47:30", - "duration": 7734000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T10:56:24", - "duration": 3816000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T12:00:00", - "duration": 11503000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T15:11:43", - "duration": 238000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T15:15:41", - "duration": 9859000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T00:00:00", - "duration": 11695000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:14:55", - "duration": 18000000, - "percent": 0.85, - "rate": 1.1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.29, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:30:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.02, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.2, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T05:30:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.29, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T08:14:55", - "duration": 905000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T08:30:00", - "duration": 4149000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T09:39:09", - "duration": 6405000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T11:25:54", - "duration": 2046000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T12:00:00", - "duration": 10914000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T15:01:54", - "duration": 3600000, - "percent": 1.25, - "rate": 0.56, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T16:01:54", - "duration": 7086000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T12:00:00", - "duration": 14774000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T16:06:14", - "duration": 789000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T16:19:23", - "duration": 6037000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T18:00:00", - "duration": 5447000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T19:30:47", - "duration": 10800000, - "percent": 1.15, - "rate": 1.03, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.9, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T22:00:00", - "duration": 10800000, - "percent": 1.15, - "rate": 1.43, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.24, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T22:30:47", - "duration": 5353000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T00:00:00", - "duration": 7351000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T02:02:31", - "duration": 5400000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T03:30:00", - "duration": 5400000, - "percent": 0.8, - "rate": 0.96, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.2, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T03:32:31", - "duration": 7049000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T00:00:00", - "duration": 829000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T00:13:49", - "duration": 2232000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T00:51:01", - "duration": 9539000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T08:30:00", - "duration": 1596000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T08:56:36", - "duration": 882000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T09:11:18", - "duration": 10122000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T18:00:00", - "duration": 124000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T18:02:04", - "duration": 5400000, - "percent": 0.85, - "rate": 0.76, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.89, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T19:32:04", - "duration": 8876000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T00:00:00", - "duration": 860000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T00:14:20", - "duration": 2644000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T00:58:24", - "duration": 9096000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T18:00:00", - "duration": 1335000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T18:22:15", - "duration": 5400000, - "percent": 0.4, - "rate": 0.36, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.9, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T19:52:15", - "duration": 7665000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T00:00:00", - "duration": 7906000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T02:11:46", - "duration": 21445000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T08:09:11", - "duration": 1249000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T00:00:00", - "duration": 6044000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T01:40:44", - "duration": 5880000, - "percent": 0.85, - "rate": 1.1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.29, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:18:31", - "duration": 9000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:18:40", - "duration": 7200000, - "percent": 0.7, - "rate": 0.91, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:30:00", - "duration": 7200000, - "percent": 0.7, - "rate": 0.84, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.2, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T05:18:40", - "duration": 680000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T12:00:00", - "duration": 8453000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T14:20:53", - "duration": 326000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T14:26:19", - "duration": 12821000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T12:00:00", - "duration": 18803000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T17:13:23", - "duration": 7200000, - "percent": 1.25, - "rate": 0.56, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T18:00:00", - "duration": 7200000, - "percent": 1.25, - "rate": 1.12, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.9, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T19:13:23", - "duration": 9106000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T21:45:09", - "duration": 251000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T21:49:20", - "duration": 640000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T05:30:00", - "duration": 9183000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T08:03:03", - "duration": 1617000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T03:30:00", - "duration": 5472000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T05:01:12", - "duration": 180000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T05:04:12", - "duration": 1548000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T18:00:00", - "duration": 13178000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T21:39:38", - "duration": 3600000, - "percent": 1.15, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.04, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T22:00:00", - "duration": 3600000, - "percent": 1.15, - "rate": 1.61, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T22:39:38", - "duration": 4822000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T12:00:00", - "duration": 4236000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T13:10:36", - "duration": 3620000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T14:10:56", - "duration": 3631000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T15:11:27", - "duration": 600000, - "percent": 0.8, - "rate": 0.48, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T15:21:15", - "duration": 7934000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T17:33:29", - "duration": 1591000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T00:00:00", - "duration": 8499000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T02:21:39", - "duration": 16200000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T03:30:00", - "duration": 16200000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.35, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T05:30:00", - "duration": 16200000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T06:51:39", - "duration": 5901000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T18:00:00", - "duration": 3812000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T19:03:32", - "duration": 6060000, - "percent": 0.75, - "rate": 0.78, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.04, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T20:44:03", - "duration": 9000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T20:44:12", - "duration": 5400000, - "percent": 0.65, - "rate": 0.68, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T22:00:00", - "duration": 5400000, - "percent": 0.65, - "rate": 0.91, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T22:14:12", - "duration": 6348000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T08:30:00", - "duration": 7596000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T10:36:36", - "duration": 5004000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T18:00:00", - "duration": 57000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T18:00:57", - "duration": 10800000, - "percent": 0.19999999999999996, - "rate": 0.18, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.9, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T21:00:57", - "duration": 2953000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T21:50:10", - "duration": 240000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T21:54:10", - "duration": 350000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T05:30:00", - "duration": 1539000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T05:55:39", - "duration": 255000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T05:59:54", - "duration": 9006000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T12:00:00", - "duration": 19916000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T17:31:56", - "duration": 9000000, - "percent": 0.6, - "rate": 0.27, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T18:00:00", - "duration": 9000000, - "percent": 0.6, - "rate": 0.54, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.9, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T20:01:56", - "duration": 7084000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T12:00:00", - "duration": 12721000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T15:32:01", - "duration": 1800000, - "percent": 0.7, - "rate": 0.31, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T16:02:01", - "duration": 7079000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T12:00:00", - "duration": 6854000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T13:54:14", - "duration": 473000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T14:02:07", - "duration": 14273000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T00:00:00", - "duration": 11831000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:17:11", - "duration": 25200000, - "percent": 0.75, - "rate": 0.97, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.29, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:30:00", - "duration": 25200000, - "percent": 0.75, - "rate": 0.9, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.2, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T05:30:00", - "duration": 25200000, - "percent": 0.75, - "rate": 0.97, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.29, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T08:30:00", - "duration": 25200000, - "percent": 0.75, - "rate": 0.93, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.24, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T10:17:11", - "duration": 6169000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T00:00:00", - "duration": 7034000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T01:57:14", - "duration": 25200000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T03:30:00", - "duration": 25200000, - "percent": 0.8, - "rate": 0.96, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.2, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T05:30:00", - "duration": 25200000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T08:30:00", - "duration": 25200000, - "percent": 0.8, - "rate": 1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.25, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T08:57:14", - "duration": 10966000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T12:00:00", - "duration": 8532000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T14:22:12", - "duration": 7200000, - "percent": 0.30000000000000004, - "rate": 0.13, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.43, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T16:22:12", - "duration": 5868000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T18:00:00", - "duration": 14095000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T21:54:55", - "duration": 280000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T21:59:35", - "duration": 25000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T03:30:00", - "duration": 6075000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T05:11:15", - "duration": 397000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T05:17:52", - "duration": 728000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T12:00:00", - "duration": 4392000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T13:13:12", - "duration": 17592000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T18:06:24", - "duration": 14016000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T08:30:00", - "duration": 9169000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T11:02:49", - "duration": 3431000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T05:30:00", - "duration": 4177000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T06:39:37", - "duration": 10025000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T09:26:42", - "duration": 9198000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T12:00:00", - "duration": 19217000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T17:20:17", - "duration": 6688000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T19:11:45", - "duration": 10095000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T00:00:00", - "duration": 1827000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T00:30:27", - "duration": 1374000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T00:53:21", - "duration": 9399000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T08:30:00", - "duration": 2264000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T09:07:44", - "duration": 7415000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T11:11:19", - "duration": 1593000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T11:37:52", - "duration": 5400000, - "percent": 1.35, - "rate": 1.89, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T12:00:00", - "duration": 5400000, - "percent": 1.35, - "rate": 0.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T13:07:52", - "duration": 17528000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T12:00:00", - "duration": 142000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T12:02:22", - "duration": 3600000, - "percent": 0.7, - "rate": 0.42, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T13:02:22", - "duration": 17858000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T08:30:00", - "duration": 5863000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T10:07:43", - "duration": 5400000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T11:37:43", - "duration": 1337000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T18:00:00", - "duration": 4181000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T19:09:41", - "duration": 3495000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T20:07:56", - "duration": 6724000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T12:00:00", - "duration": 5103000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T13:25:03", - "duration": 76000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T13:26:19", - "duration": 16421000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T18:00:00", - "duration": 13638000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T21:47:18", - "duration": 533000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T21:56:11", - "duration": 229000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T18:00:00", - "duration": 2999000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T18:49:59", - "duration": 3600000, - "percent": 1.45, - "rate": 1.52, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T19:49:59", - "duration": 7801000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T00:00:00", - "duration": 2319000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T00:38:39", - "duration": 7200000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T02:38:39", - "duration": 3081000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T00:00:00", - "duration": 1518000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T00:25:18", - "duration": 3600000, - "percent": 0.7, - "rate": 1.05, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T01:25:18", - "duration": 7482000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T05:30:00", - "duration": 1230000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T05:50:30", - "duration": 18830000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T11:04:20", - "duration": 3340000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T12:00:00", - "duration": 19246000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T17:20:46", - "duration": 7200000, - "percent": 1.7, - "rate": 1.02, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T18:00:00", - "duration": 7200000, - "percent": 1.7, - "rate": 1.78, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T19:20:46", - "duration": 9554000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T08:30:00", - "duration": 2085000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T09:04:45", - "duration": 4217000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T10:15:02", - "duration": 6298000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T12:00:00", - "duration": 17944000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T16:59:04", - "duration": 3600000, - "percent": 1.65, - "rate": 0.99, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T17:59:04", - "duration": 56000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T18:00:00", - "duration": 5666000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T19:34:26", - "duration": 5400000, - "percent": 1.9, - "rate": 1.99, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T21:04:26", - "duration": 3334000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T00:00:00", - "duration": 2082000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T00:34:42", - "duration": 3600000, - "percent": 1.35, - "rate": 2.02, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T01:34:42", - "duration": 6918000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T12:00:00", - "duration": 5752000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T13:35:52", - "duration": 204000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T13:39:16", - "duration": 5345000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T15:08:21", - "duration": 5400000, - "percent": 1.55, - "rate": 0.93, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T16:38:21", - "duration": 4899000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T18:00:00", - "duration": 6720000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T19:52:00", - "duration": 645000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T20:02:45", - "duration": 7035000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T05:30:00", - "duration": 9805000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:13:25", - "duration": 5400000, - "percent": 1.5, - "rate": 2.32, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:30:00", - "duration": 5400000, - "percent": 1.5, - "rate": 2.1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T09:43:25", - "duration": 8195000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T12:00:00", - "duration": 2532000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T12:42:12", - "duration": 4620000, - "percent": 1.4, - "rate": 0.84, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T13:58:48", - "duration": 14000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T13:59:02", - "duration": 5400000, - "percent": 1.55, - "rate": 0.93, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T15:29:02", - "duration": 6819000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T17:22:41", - "duration": 7200000, - "percent": 1.35, - "rate": 0.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T18:00:00", - "duration": 7200000, - "percent": 1.35, - "rate": 1.41, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.04, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T19:22:41", - "duration": 9439000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T00:00:00", - "duration": 9113000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T02:31:53", - "duration": 5400000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T03:30:00", - "duration": 5400000, - "percent": 1.25, - "rate": 1.68, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.34, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T04:01:53", - "duration": 5287000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T08:30:00", - "duration": 4914000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T09:51:54", - "duration": 9000000, - "percent": 0.8, - "rate": 1.12, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T12:00:00", - "duration": 9000000, - "percent": 0.8, - "rate": 0.48, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T12:21:54", - "duration": 20286000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T18:00:00", - "duration": 1416000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T18:23:36", - "duration": 10800000, - "percent": 1.5, - "rate": 1.57, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T21:23:36", - "duration": 2184000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T08:30:00", - "duration": 3040000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T09:20:40", - "duration": 3159000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T10:13:19", - "duration": 6401000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T12:00:00", - "duration": 4788000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T13:19:48", - "duration": 7200000, - "percent": 1.45, - "rate": 0.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T15:19:48", - "duration": 4339000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T16:32:07", - "duration": 7200000, - "percent": 1.5, - "rate": 0.9, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T18:00:00", - "duration": 7200000, - "percent": 1.5, - "rate": 1.57, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T18:32:07", - "duration": 12473000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T18:00:00", - "duration": 4755000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T19:19:15", - "duration": 9000000, - "percent": 1.5, - "rate": 1.57, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T21:49:15", - "duration": 645000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T18:00:00", - "duration": 12431000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T21:27:11", - "duration": 10800000, - "percent": 1.95, - "rate": 2.04, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T22:00:00", - "duration": 10800000, - "percent": 1.95, - "rate": 2.73, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T00:00:00", - "duration": 10800000, - "percent": 1.95, - "rate": 2.92, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T00:27:11", - "duration": 10969000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T18:00:00", - "duration": 260000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T18:04:20", - "duration": 3314000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T18:59:34", - "duration": 7000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T18:59:41", - "duration": 45000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T19:00:26", - "duration": 10774000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T05:30:00", - "duration": 7859000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T07:40:59", - "duration": 36000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T07:41:35", - "duration": 2905000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T08:30:00", - "duration": 5764000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T10:06:04", - "duration": 7200000, - "percent": 1.25, - "rate": 1.75, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T12:00:00", - "duration": 7200000, - "percent": 1.25, - "rate": 0.75, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T12:06:04", - "duration": 21236000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T08:30:00", - "duration": 11084000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T11:34:44", - "duration": 3600000, - "percent": 0.7, - "rate": 0.98, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T12:00:00", - "duration": 3600000, - "percent": 0.7, - "rate": 0.42, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T12:34:44", - "duration": 19516000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T12:00:00", - "duration": 12872000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T15:34:32", - "duration": 4983000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T16:57:35", - "duration": 3745000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T18:00:00", - "duration": 5583000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T19:33:03", - "duration": 7200000, - "percent": 1.55, - "rate": 1.62, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T21:33:03", - "duration": 1617000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T00:00:00", - "duration": 2776000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T00:46:16", - "duration": 7200000, - "percent": 1.3, - "rate": 2.01, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T02:46:16", - "duration": 2624000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T22:00:00", - "duration": 1978000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T22:32:58", - "duration": 14400000, - "percent": 1.75, - "rate": 2.45, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T00:00:00", - "duration": 14400000, - "percent": 1.75, - "rate": 2.71, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T02:32:58", - "duration": 3422000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T05:30:00", - "duration": 8216000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T07:46:56", - "duration": 670000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T07:58:06", - "duration": 9000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T07:58:15", - "duration": 3600000, - "percent": 1.45, - "rate": 2.24, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T08:30:00", - "duration": 3600000, - "percent": 1.45, - "rate": 2.03, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T08:58:15", - "duration": 10905000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T18:00:00", - "duration": 1977000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T18:32:57", - "duration": 4784000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T19:52:41", - "duration": 7639000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T08:30:00", - "duration": 993000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T08:46:33", - "duration": 11607000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T03:30:00", - "duration": 14251000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T07:27:31", - "duration": 3604000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T08:27:35", - "duration": 145000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T12:00:00", - "duration": 1528000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T12:25:28", - "duration": 5400000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T13:55:27", - "duration": 14673000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:00:00", - "duration": 887000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:14:47", - "duration": 60000, - "percent": 0.6, - "rate": 0.99, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:15:04", - "duration": 23000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:15:27", - "duration": 3147000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T01:07:54", - "duration": 435000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T04:15:09", - "duration": 14000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T04:15:23", - "duration": 9240000, - "percent": 0.65, - "rate": 1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T06:46:52", - "duration": 297000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T06:51:49", - "duration": 17000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T06:52:06", - "duration": 3600000, - "percent": 0.85, - "rate": 1.31, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T07:52:06", - "duration": 2274000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T18:00:00", - "duration": 10401000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T20:53:21", - "duration": 16200000, - "percent": 1.65, - "rate": 1.89, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T22:00:00", - "duration": 16200000, - "percent": 1.65, - "rate": 2.39, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T00:00:00", - "duration": 16200000, - "percent": 1.65, - "rate": 2.72, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T01:23:21", - "duration": 566000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T01:32:47", - "duration": 12600000, - "percent": 1.65, - "rate": 2.72, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T03:30:00", - "duration": 12600000, - "percent": 1.65, - "rate": 2.55, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T05:02:47", - "duration": 12433000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T12:00:00", - "duration": 18910000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T17:15:10", - "duration": 10800000, - "percent": 1.45, - "rate": 0.94, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T18:00:00", - "duration": 10800000, - "percent": 1.45, - "rate": 1.66, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.14, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T20:15:10", - "duration": 6290000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T12:00:00", - "duration": 8739000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T14:25:39", - "duration": 1563000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T14:51:42", - "duration": 5877000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T16:29:39", - "duration": 10800000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T18:00:00", - "duration": 10800000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T19:29:39", - "duration": 9021000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T18:00:00", - "duration": 813000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T18:13:33", - "duration": 18000000, - "percent": 1.65, - "rate": 1.89, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T22:00:00", - "duration": 18000000, - "percent": 1.65, - "rate": 2.39, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T23:13:33", - "duration": 2787000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T12:00:00", - "duration": 12800000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T15:33:20", - "duration": 256000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T15:37:36", - "duration": 8544000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T00:00:00", - "duration": 586000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T00:09:46", - "duration": 12600000, - "percent": 1.7, - "rate": 2.8, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T03:30:00", - "duration": 12600000, - "percent": 1.7, - "rate": 2.63, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T03:39:46", - "duration": 17414000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T12:00:00", - "duration": 17302000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T16:48:22", - "duration": 7200000, - "percent": 1.6, - "rate": 1.04, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T18:00:00", - "duration": 7200000, - "percent": 1.6, - "rate": 1.84, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T18:48:22", - "duration": 11498000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T12:00:00", - "duration": 19646000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T17:27:26", - "duration": 10800000, - "percent": 1.75, - "rate": 1.13, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T18:00:00", - "duration": 10800000, - "percent": 1.75, - "rate": 2.01, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T20:27:26", - "duration": 5554000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T22:00:00", - "duration": 3002000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T22:50:02", - "duration": 416000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T22:56:58", - "duration": 3782000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T12:00:00", - "duration": 11357000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T15:09:17", - "duration": 12600000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T18:00:00", - "duration": 12600000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T18:39:17", - "duration": 12043000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T08:30:00", - "duration": 9912000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T11:15:12", - "duration": 9000000, - "percent": 0.4, - "rate": 0.58, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T12:00:00", - "duration": 8340000, - "percent": 0.4, - "rate": 0.26, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T13:33:32", - "duration": 38000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T10:34:10", - "duration": 627000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T10:44:37", - "duration": 3600000, - "percent": 1.15, - "rate": 1.66, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T11:44:37", - "duration": 923000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T18:00:00", - "duration": 10191000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T20:49:51", - "duration": 12600000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T22:00:00", - "duration": 12600000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T00:00:00", - "duration": 12600000, - "percent": 1.4, - "rate": 2.31, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T00:19:51", - "duration": 11409000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T03:30:00", - "duration": 2088000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T04:04:48", - "duration": 20248000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T09:42:16", - "duration": 8264000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T12:00:00", - "duration": 7234000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T14:00:34", - "duration": 5400000, - "percent": 1.6, - "rate": 1.04, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T15:30:34", - "duration": 8966000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T03:30:00", - "duration": 16729000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:08:49", - "duration": 7200000, - "percent": 1.5, - "rate": 2.32, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:30:00", - "duration": 7200000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T10:08:49", - "duration": 6671000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T12:00:00", - "duration": 65000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T12:01:05", - "duration": 421000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T12:08:06", - "duration": 21114000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T18:00:00", - "duration": 4889000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T19:21:29", - "duration": 14570000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T23:24:19", - "duration": 2141000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T03:30:00", - "duration": 13402000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T07:13:22", - "duration": 17773000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T12:09:35", - "duration": 5452000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T13:40:27", - "duration": 9000000, - "percent": 1.5, - "rate": 0.97, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T16:10:27", - "duration": 6573000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T03:30:00", - "duration": 6646000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T05:20:46", - "duration": 81000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T04:22:07", - "duration": 14873000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T18:00:00", - "duration": 3581000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "annotations": [{ "code": "basal/unknown-duration" }], - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T18:59:41", - "duration": 0 - } -] -` - -func GetPlatformBasalData() []map[string]interface{} { - data := []map[string]interface{}{} - json.Unmarshal([]byte(platformBasalStr), &data) - return data -} diff --git a/migrations/20231128_jellyfish_migration/verify/data_verify.go b/migrations/20231128_jellyfish_migration/verify/data_verify.go index d3d36f3be0..3c29c5ec3e 100644 --- a/migrations/20231128_jellyfish_migration/verify/data_verify.go +++ b/migrations/20231128_jellyfish_migration/verify/data_verify.go @@ -62,6 +62,48 @@ func NewDataVerify(ctx context.Context, dataC *mongo.Collection) (*DataVerify, e var DatasetTypes = []string{"cbg", "smbg", "basal", "bolus", "deviceEvent", "wizard", "pumpSettings"} +//archivedDatasetId + +func (m *DataVerify) fetchDataSetNotDeduped(uploadID string, dataTypes []string) (map[string][]map[string]interface{}, error) { + if m.dataC == nil { + return nil, errors.New("missing data collection") + } + + typeSet := map[string][]map[string]interface{}{} + + for _, dType := range dataTypes { + + dset := []map[string]interface{}{} + + filter := bson.M{ + "uploadId": uploadID, + "type": dType, + "_active": true, + } + + sort := bson.D{{Key: "time", Value: 1}} + + if dType == "deviceEvent" || dType == "bolus" { + sort = bson.D{{Key: "time", Value: 1}, {Key: "subType", Value: 1}} + } + + dDataCursor, err := m.dataC.Find(m.ctx, filter, &options.FindOptions{ + Sort: sort, + }) + if err != nil { + return nil, err + } + defer dDataCursor.Close(m.ctx) + + if err := dDataCursor.All(m.ctx, &dset); err != nil { + return nil, err + } + log.Printf("got dataset [%s][%s][%d] results", uploadID, dType, len(dset)) + typeSet[dType] = dset + } + return typeSet, nil +} + func (m *DataVerify) fetchDataSet(uploadID string, dataTypes []string) (map[string][]map[string]interface{}, error) { if m.dataC == nil { return nil, errors.New("missing data collection") @@ -243,7 +285,7 @@ var dataTypePathIgnored = map[string][]string{ "bolus": {"normal"}, } -func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUploadID string, dataTyes []string) error { +func (m *DataVerify) VerifyAPIDifferences(platformUploadID string, jellyfishUploadID string, dataTyes []string) error { if len(dataTyes) == 0 { dataTyes = DatasetTypes @@ -292,6 +334,28 @@ func (m *DataVerify) Verify(ref string, platformUploadID string, jellyfishUpload return nil } +func (m *DataVerify) VerifyDeduped(uploadID string, dataTyes []string) error { + + if len(dataTyes) == 0 { + dataTyes = DatasetTypes + } + dataset, err := m.fetchDataSetNotDeduped(uploadID, dataTyes) + if err != nil { + return err + } + + if len(dataset) != 0 { + log.Printf("dataset should have been deduped but [%d] records are active", len(dataset)) + notDedupedPath := filepath.Join(".", "_not_deduped", uploadID) + for dType, dTypeItems := range dataset { + if len(dTypeItems) > 0 { + writeFileData(dTypeItems, notDedupedPath, fmt.Sprintf("%s_not_deduped_datums.json", dType), true) + } + } + } + return nil +} + func writeFileData(data interface{}, path string, name string, asJSON bool) { if data == nil || path == "" || name == "" { return diff --git a/migrations/20231128_jellyfish_migration/verify/verify.go b/migrations/20231128_jellyfish_migration/verify/verify.go index 029e3c58e5..a29e4b3409 100644 --- a/migrations/20231128_jellyfish_migration/verify/verify.go +++ b/migrations/20231128_jellyfish_migration/verify/verify.go @@ -7,7 +7,6 @@ import ( "os" "strings" - "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" "github.com/urfave/cli" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" @@ -24,8 +23,10 @@ type Verify struct { type config struct { mongoURI string findBlobs bool + verifyDeduped bool platformUploadID string jellyfishUploadID string + uploadIdDeduped string dataTypes string } @@ -33,6 +34,8 @@ const MongoURIFlag = "uri" const PlatformUploadIDFlag = "upload-id-platform" const JellyfishUploadIDFlag = "upload-id-jellyfish" const FindBlobFlag = "find-blobs" +const VerifyDedupedFlag = "verify-deduped" +const UploadIdDedupedFlag = "upload-id" const DataTypesFlag = "data-types" const UseSubsetFlag = "use-subset" @@ -79,6 +82,18 @@ func (m *Verify) RunAndExit() { return m.verificationUtil.WriteBlobIDs() } + if m.config.verifyDeduped { + m.verificationUtil, err = NewDataVerify( + m.ctx, + m.client.Database("data").Collection("deviceData"), + ) + + if err != nil { + return fmt.Errorf("unable to create verification utils : %w", err) + } + return m.verificationUtil.VerifyDeduped(m.config.uploadIdDeduped, strings.Split(m.config.dataTypes, ",")) + } + m.verificationUtil, err = NewDataVerify( m.ctx, m.client.Database("data").Collection("deviceData"), @@ -88,7 +103,7 @@ func (m *Verify) RunAndExit() { return fmt.Errorf("unable to create verification utils : %w", err) } - err = m.verificationUtil.Verify("ref", m.config.platformUploadID, m.config.jellyfishUploadID, strings.Split(m.config.dataTypes, ",")) + err = m.verificationUtil.VerifyAPIDifferences(m.config.platformUploadID, m.config.jellyfishUploadID, strings.Split(m.config.dataTypes, ",")) if err != nil { log.Printf("error running verify : %s", err.Error()) } @@ -125,12 +140,18 @@ func (m *Verify) Initialize() error { Destination: &m.config.jellyfishUploadID, Required: false, }, + cli.StringFlag{ + Name: UploadIdDedupedFlag, + Usage: "uploadID of the dataset to check deduping of", + Destination: &m.config.uploadIdDeduped, + Required: false, + }, cli.StringFlag{ Name: DataTypesFlag, Usage: "comma seperated list of data types to compare", Destination: &m.config.dataTypes, Required: false, - Value: strings.Join(utils.DatasetTypes, ","), + Value: strings.Join(DatasetTypes, ","), }, cli.BoolFlag{ Name: FindBlobFlag, @@ -138,6 +159,12 @@ func (m *Verify) Initialize() error { Destination: &m.config.findBlobs, Required: false, }, + cli.BoolFlag{ + Name: VerifyDedupedFlag, + Usage: "verify that a dataset has been deduplicated", + Destination: &m.config.verifyDeduped, + Required: false, + }, cli.StringFlag{ Name: MongoURIFlag, Usage: "mongo connection URI", From f7960eb8e345627618bbf8d390451a40ee40b451 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 30 Jul 2024 15:46:48 +1200 Subject: [PATCH 367/413] fix tandem model --- data/deduplicator/deduplicator/device_deactivate_hash.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index 6eb70974cb..56a0c1c74f 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -36,7 +36,7 @@ var DeviceDeactivateLegacyHasheManufacturerDeviceModels = map[string][]string{ "i-SENS": {"CareSens"}, "MicroTech": {"Equil"}, "Roche": {"Aviva Connect", "Performa Connect", "Guide", "Instant (single-button)", "Guide Me", "Instant (two-button)", "Instant S (single-button)", "ReliOn Platinum"}, - "Tandem": {"T:Slim"}, + "Tandem": {"1002717"}, } type DeviceDeactivateHash struct { From f1e15a666f4d06a48c073fd699c80e3e76cd5007 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jul 2024 11:12:26 +1200 Subject: [PATCH 368/413] Legacy Field Updates --- data/types/base.go | 2 +- data/types/base_test.go | 12 ++++++++++++ .../glucose/selfmonitored/selfmonitored_test.go | 15 ++++++++------- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/data/types/base.go b/data/types/base.go index 3eec54c7b8..0decd6bb79 100644 --- a/data/types/base.go +++ b/data/types/base.go @@ -26,7 +26,7 @@ const ( TagLengthMaximum = 100 TagsLengthMaximum = 100 TimeFormat = time.RFC3339Nano - LegacyFieldTimeFormat = "2006-01-02T15:04:05.999+07:00" + LegacyFieldTimeFormat = "2006-01-02T15:04:05.999Z" TimeZoneOffsetMaximum = 7 * 24 * 60 // TODO: Fix! Limit to reasonable values TimeZoneOffsetMinimum = -7 * 24 * 60 // TODO: Fix! Limit to reasonable values VersionInternalMinimum = 0 diff --git a/data/types/base_test.go b/data/types/base_test.go index aaecaa3b4b..5c7721ef51 100644 --- a/data/types/base_test.go +++ b/data/types/base_test.go @@ -1003,6 +1003,18 @@ var _ = Describe("Base", func() { Expect(legacyIDFields).To(Equal([]string{"one", "two", "three"})) }) }) + + Context("GetLegacyTimeField", func() { + It("returns expected format", func() { + Expect(types.LegacyFieldTimeFormat).To(Equal("2006-01-02T15:04:05.999Z")) + }) + It("returns expected legacy field details", func() { + t := time.Date(2015, time.July, 31, 23, 59, 59, 999999999, time.UTC) + legacyTimeField := types.GetLegacyTimeField(&t) + Expect(legacyTimeField.Name).To(Equal("time")) + Expect(*legacyTimeField.Value).To(Equal("2015-07-31T23:59:59.999Z")) + }) + }) }) Context("GetPayload", func() { diff --git a/data/types/blood/glucose/selfmonitored/selfmonitored_test.go b/data/types/blood/glucose/selfmonitored/selfmonitored_test.go index 943cc17772..db25ac2ed2 100644 --- a/data/types/blood/glucose/selfmonitored/selfmonitored_test.go +++ b/data/types/blood/glucose/selfmonitored/selfmonitored_test.go @@ -1,13 +1,11 @@ package selfmonitored_test import ( - "strconv" "time" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - dataBloodGlucose "github.com/tidepool-org/platform/data/blood/glucose" dataBloodGlucoseTest "github.com/tidepool-org/platform/data/blood/glucose/test" dataNormalizer "github.com/tidepool-org/platform/data/normalizer" "github.com/tidepool-org/platform/data/types" @@ -38,6 +36,12 @@ func NewSelfMonitored(units *string) *selfmonitored.SelfMonitored { return datum } +func NewSelfMonitoredWithValue(units *string, val *float64) *selfmonitored.SelfMonitored { + datum := NewSelfMonitored(units) + datum.Value = pointer.FromFloat64(*val) + return datum +} + func CloneSelfMonitored(datum *selfmonitored.SelfMonitored) *selfmonitored.SelfMonitored { if datum == nil { return nil @@ -501,7 +505,7 @@ var _ = Describe("SelfMonitored", func() { var datum *selfmonitored.SelfMonitored BeforeEach(func() { - datum = NewSelfMonitored(pointer.FromString("mg/dl")) + datum = NewSelfMonitoredWithValue(pointer.FromString("mg/dl"), pointer.FromFloat64(144)) normalizer := dataNormalizer.New() Expect(normalizer).ToNot(BeNil()) datum.Normalize(normalizer.WithOrigin(structure.OriginExternal)) @@ -559,10 +563,7 @@ var _ = Describe("SelfMonitored", func() { It("returns the expected legacy identity fields", func() { legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - value, units, err := datum.GetRawValueAndUnits() - Expect(err).ToNot(HaveOccurred()) - fullPrecisionValue := dataBloodGlucose.NormalizeValueForUnitsWithFullPrecision(value, units) - Expect(legacyIdentityFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat), strconv.FormatFloat(*fullPrecisionValue, 'f', -1, 64)})) + Expect(legacyIdentityFields).To(Equal([]string{"smbg", *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat), "7.993077107105568"})) }) }) }) From 4ac6f5c41ca69395be12d5404f370d7903db0e3d Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jul 2024 16:38:34 +1200 Subject: [PATCH 369/413] expand type LegacyIdentityFields tests --- data/deduplicator/deduplicator/hash_test.go | 36 +++++++++++++------ data/types/activity/physical/physical_test.go | 8 ++++- data/types/basal/basal_test.go | 7 +++- data/types/base.go | 3 +- data/types/base_test.go | 3 -- data/types/blood/blood_test.go | 7 +++- .../glucose/selfmonitored/selfmonitored.go | 3 +- .../selfmonitored/selfmonitored_test.go | 10 +++++- data/types/bolus/bolus_test.go | 7 +++- data/types/device/device_test.go | 7 +++- data/types/food/food_test.go | 8 ++++- data/types/insulin/insulin_test.go | 8 ++++- data/types/settings/cgm/cgm_test.go | 9 +++-- 13 files changed, 88 insertions(+), 28 deletions(-) diff --git a/data/deduplicator/deduplicator/hash_test.go b/data/deduplicator/deduplicator/hash_test.go index e65cfb9aa1..e04efb709e 100644 --- a/data/deduplicator/deduplicator/hash_test.go +++ b/data/deduplicator/deduplicator/hash_test.go @@ -134,16 +134,30 @@ var _ = Describe("Hash", func() { Expect(hash).To(BeEmpty()) }) - It("successfully returns same hash as legacy smbg expects", func() { - Expect(dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash([]string{"smbg", "tools", "2014-06-11T11:12:43.029Z", "5.550747991045533"})).To(Equal("e2ihon9nqcro96c4uugb4ftdnr07nqok")) - }) - - It("successfully returns same hash as legacy basal expects", func() { - Expect(dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash([]string{"basal", "scheduled", "tools", "2014-06-11T06:00:00.000Z"})).To(Equal("cjou7vscvp8ogv34d6vejootulqfn3jd")) - }) - - It("successfully returns same hash as legacy cbg expects", func() { - Expect(dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash([]string{"cbg", "DexHealthKit_Dexcom:com.dexcom.Share2:3.0.4.17", "2015-12-21T11:23:08Z"})).To(Equal("nsikjhfaprplpq78hc7di2lu5qpt1e3k")) - }) + DescribeTable("hash from legacy identity tests", + func(fields []string, expectedHash string, expectedErr error) { + actualHash, actualErr := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash(fields) + if expectedErr != nil { + Expect(actualErr).To(Equal(expectedErr)) + } else { + Expect(actualHash).To(Equal(expectedHash)) + Expect(actualErr).To(BeNil()) + } + }, + Entry("smbg id", []string{"smbg", "tools", "2014-06-11T11:12:43.029Z", "5.550747991045533"}, "e2ihon9nqcro96c4uugb4ftdnr07nqok", nil), + Entry("smbg id", []string{"smbg", "tools", "2014-06-11T17:57:01.703Z", "4.5"}, "c14eds071pp5gsirfmgmsclbcahs8th0", nil), + Entry("smbg id", []string{"smbg", "tools", "2015-07-04T10:13:00.000Z", "4.9"}, "rk2htms97m7hipdu5lrso7ufd3pedm6n", nil), + Entry("smbg id", []string{"smbg", "tools", "2015-07-04T10:13:00.000Z", "4.8"}, "urrkdln86rl4vhqckps6gnupg5njqk6n", nil), + + Entry("cbg id", []string{"cbg", "tools", "2014-06-11T11:12:43.029Z"}, "eb12p6h892pmd0hhccpt2r17muc407o0", nil), + Entry("cbg id", []string{"cbg", "tools", "2014-06-11T17:57:01.703Z"}, "ha2ogn1kenqqhseed504sqnanhnclg5s", nil), + Entry("cbg id", []string{"cbg", "tools", "2014-06-12T11:12:43.029Z"}, "i922lobl3kron3t81pjap31anopkspvb", nil), + Entry("cbg id", []string{"cbg", "DexHealthKit_Dexcom:com.dexcom.Share2:3.0.4.17", "2015-12-21T11:23:08Z"}, "nsikjhfaprplpq78hc7di2lu5qpt1e3k", nil), + + Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T00:00:00.000Z"}, "kmm427pfbrc6rugtmbuli8j4q61u17uk", nil), + Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T06:00:00.000Z"}, "cjou7vscvp8ogv34d6vejootulqfn3jd", nil), + Entry("basal id", []string{"basal", "temp", "tools", "2014-06-11T09:00:00.000Z"}, "tn33bjb0241j9qh4jg9vdnf1g6k1g9r8", nil), + Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T19:00:00.000Z"}, "kftn188l8rjuvma3qkd3iqg34t0plajp", nil), + ) }) }) diff --git a/data/types/activity/physical/physical_test.go b/data/types/activity/physical/physical_test.go index ad9f08c128..f69ad75d9b 100644 --- a/data/types/activity/physical/physical_test.go +++ b/data/types/activity/physical/physical_test.go @@ -1,6 +1,8 @@ package physical_test import ( + "time" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -1366,9 +1368,13 @@ var _ = Describe("Physical", func() { Context("LegacyIdentityFields", func() { It("returns the expected legacy identity fields", func() { datum := NewPhysical() + datum.DeviceID = pointer.FromString("some-device") + t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") + Expect(err).ToNot(HaveOccurred()) + datum.Time = pointer.FromTime(t) legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat)})) + Expect(legacyIdentityFields).To(Equal([]string{"physicalActivity", "some-device", "2023-05-13T15:51:58Z"})) }) }) }) diff --git a/data/types/basal/basal_test.go b/data/types/basal/basal_test.go index 4efabd6275..b83559cb0c 100644 --- a/data/types/basal/basal_test.go +++ b/data/types/basal/basal_test.go @@ -141,9 +141,14 @@ var _ = Describe("Basal", func() { }) It("returns the expected legacy identity fields", func() { + datum.DeviceID = pointer.FromString("some-device") + t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") + Expect(err).ToNot(HaveOccurred()) + datum.Time = pointer.FromTime(t) + datum.DeliveryType = "some-delivery" legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{datum.Type, datum.DeliveryType, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat)})) + Expect(legacyIdentityFields).To(Equal([]string{"basal", "some-delivery", "some-device", "2023-05-13T15:51:58Z"})) }) }) }) diff --git a/data/types/base.go b/data/types/base.go index 0decd6bb79..6cc8d4be88 100644 --- a/data/types/base.go +++ b/data/types/base.go @@ -26,7 +26,6 @@ const ( TagLengthMaximum = 100 TagsLengthMaximum = 100 TimeFormat = time.RFC3339Nano - LegacyFieldTimeFormat = "2006-01-02T15:04:05.999Z" TimeZoneOffsetMaximum = 7 * 24 * 60 // TODO: Fix! Limit to reasonable values TimeZoneOffsetMinimum = -7 * 24 * 60 // TODO: Fix! Limit to reasonable values VersionInternalMinimum = 0 @@ -279,7 +278,7 @@ func GetLegacyTimeField(t *time.Time) LegacyIDField { return LegacyIDField{Name: "time", Value: &tVal} } - tVal = (*t).Format(LegacyFieldTimeFormat) + tVal = (*t).Format(TimeFormat) return LegacyIDField{Name: "time", Value: &tVal} } diff --git a/data/types/base_test.go b/data/types/base_test.go index 5c7721ef51..d6c0fe77af 100644 --- a/data/types/base_test.go +++ b/data/types/base_test.go @@ -1005,9 +1005,6 @@ var _ = Describe("Base", func() { }) Context("GetLegacyTimeField", func() { - It("returns expected format", func() { - Expect(types.LegacyFieldTimeFormat).To(Equal("2006-01-02T15:04:05.999Z")) - }) It("returns expected legacy field details", func() { t := time.Date(2015, time.July, 31, 23, 59, 59, 999999999, time.UTC) legacyTimeField := types.GetLegacyTimeField(&t) diff --git a/data/types/blood/blood_test.go b/data/types/blood/blood_test.go index 75031c1b3d..ff36e7b418 100644 --- a/data/types/blood/blood_test.go +++ b/data/types/blood/blood_test.go @@ -132,9 +132,14 @@ var _ = Describe("Blood", func() { Context("LegacyIdentityFields", func() { It("returns the expected legacy identity fields", func() { datum := dataTypesBloodTest.NewBlood() + datum.Type = "bg" + datum.DeviceID = pointer.FromString("some-bg-device") + t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") + Expect(err).ToNot(HaveOccurred()) + datum.Time = pointer.FromTime(t) legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat)})) + Expect(legacyIdentityFields).To(Equal([]string{"bg", "some-bg-device", "2023-05-13T15:51:58Z"})) }) }) diff --git a/data/types/blood/glucose/selfmonitored/selfmonitored.go b/data/types/blood/glucose/selfmonitored/selfmonitored.go index f64e430a19..567369d8fe 100644 --- a/data/types/blood/glucose/selfmonitored/selfmonitored.go +++ b/data/types/blood/glucose/selfmonitored/selfmonitored.go @@ -83,5 +83,6 @@ func (s *SelfMonitored) LegacyIdentityFields() ([]string, error) { return nil, err } fullPrecisionValue := dataBloodGlucose.NormalizeValueForUnitsWithFullPrecision(value, units) - return append(identityFields, strconv.FormatFloat(*fullPrecisionValue, 'f', -1, 64)), nil + identityFields = append(identityFields, strconv.FormatFloat(*fullPrecisionValue, 'f', -1, 64)) + return identityFields, nil } diff --git a/data/types/blood/glucose/selfmonitored/selfmonitored_test.go b/data/types/blood/glucose/selfmonitored/selfmonitored_test.go index db25ac2ed2..7c7610763d 100644 --- a/data/types/blood/glucose/selfmonitored/selfmonitored_test.go +++ b/data/types/blood/glucose/selfmonitored/selfmonitored_test.go @@ -561,9 +561,17 @@ var _ = Describe("SelfMonitored", func() { }) It("returns the expected legacy identity fields", func() { + datum = NewSelfMonitoredWithValue(pointer.FromString("mg/dl"), pointer.FromFloat64(220)) + normalizer := dataNormalizer.New() + Expect(normalizer).ToNot(BeNil()) + datum.Normalize(normalizer.WithOrigin(structure.OriginExternal)) + datum.DeviceID = pointer.FromString("some-device") + t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") + Expect(err).ToNot(HaveOccurred()) + datum.Time = pointer.FromTime(t) legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{"smbg", *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat), "7.993077107105568"})) + Expect(legacyIdentityFields).To(Equal([]string{"smbg", "some-device", "2023-05-13T15:51:58Z", "12.211645580300173"})) }) }) }) diff --git a/data/types/bolus/bolus_test.go b/data/types/bolus/bolus_test.go index 1f31e9ac9f..79642af8c8 100644 --- a/data/types/bolus/bolus_test.go +++ b/data/types/bolus/bolus_test.go @@ -204,9 +204,14 @@ var _ = Describe("Bolus", func() { }) It("returns the expected legacy identity fields", func() { + datum.DeviceID = pointer.FromString("some-device") + t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") + Expect(err).ToNot(HaveOccurred()) + datum.Time = pointer.FromTime(t) + datum.SubType = "some-sub-type" legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{datum.Type, datum.SubType, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat)})) + Expect(legacyIdentityFields).To(Equal([]string{"bolus", "some-sub-type", "some-device", "2023-05-13T15:51:58Z"})) }) }) }) diff --git a/data/types/device/device_test.go b/data/types/device/device_test.go index a8067e5c90..70ab8bec82 100644 --- a/data/types/device/device_test.go +++ b/data/types/device/device_test.go @@ -142,9 +142,14 @@ var _ = Describe("Device", func() { }) It("returns the expected legacy identity fields", func() { + datum.DeviceID = pointer.FromString("some-device") + t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") + Expect(err).ToNot(HaveOccurred()) + datum.Time = pointer.FromTime(t) + datum.SubType = "some-sub-type" legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{datum.Type, datum.SubType, (*datum.Time).Format(types.LegacyFieldTimeFormat), *datum.DeviceID})) + Expect(legacyIdentityFields).To(Equal([]string{"deviceEvent", "some-sub-type", "2023-05-13T15:51:58Z", "some-device"})) }) }) }) diff --git a/data/types/food/food_test.go b/data/types/food/food_test.go index c63c0559fe..728e34fb93 100644 --- a/data/types/food/food_test.go +++ b/data/types/food/food_test.go @@ -1,6 +1,8 @@ package food_test import ( + "time" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -436,9 +438,13 @@ var _ = Describe("Food", func() { Context("LegacyIdentityFields", func() { It("returns the expected legacy identity fields", func() { datum := dataTypesFoodTest.RandomFood(3) + datum.DeviceID = pointer.FromString("some-device") + t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") + Expect(err).ToNot(HaveOccurred()) + datum.Time = pointer.FromTime(t) legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat)})) + Expect(legacyIdentityFields).To(Equal([]string{"food", "some-device", "2023-05-13T15:51:58Z"})) }) }) }) diff --git a/data/types/insulin/insulin_test.go b/data/types/insulin/insulin_test.go index 5d5ead6ac4..92ab70ad70 100644 --- a/data/types/insulin/insulin_test.go +++ b/data/types/insulin/insulin_test.go @@ -1,6 +1,8 @@ package insulin_test import ( + "time" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -170,9 +172,13 @@ var _ = Describe("Insulin", func() { Context("LegacyIdentityFields", func() { It("returns the expected legacy identity fields", func() { datum := NewInsulin() + datum.DeviceID = pointer.FromString("some-pump-device") + t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") + Expect(err).ToNot(HaveOccurred()) + datum.Time = pointer.FromTime(t) legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyFieldTimeFormat)})) + Expect(legacyIdentityFields).To(Equal([]string{"insulin", "some-pump-device", "2023-05-13T15:51:58Z"})) }) }) }) diff --git a/data/types/settings/cgm/cgm_test.go b/data/types/settings/cgm/cgm_test.go index b833eaa38b..40ed5f685d 100644 --- a/data/types/settings/cgm/cgm_test.go +++ b/data/types/settings/cgm/cgm_test.go @@ -2,6 +2,7 @@ package cgm_test import ( "sort" + "time" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -597,13 +598,15 @@ var _ = Describe("CGM", func() { }) Context("LegacyIdentityFields", func() { - It("returns the expected legacy identity fields", func() { - datum := dataTypesSettingsCgmTest.RandomCGM(pointer.FromString("mmol/l")) + datum.DeviceID = pointer.FromString("some-cgm-device") + t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") + Expect(err).ToNot(HaveOccurred()) + datum.Time = pointer.FromTime(t) legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{datum.Type, (*datum.Time).Format(types.LegacyFieldTimeFormat), *datum.DeviceID})) + Expect(legacyIdentityFields).To(Equal([]string{"cgmSettings", "2023-05-13T15:51:58Z", "some-cgm-device"})) }) }) }) From f67d41cb10684559ad051023d4effe7ebc9e1f3d Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 31 Jul 2024 17:39:36 +1200 Subject: [PATCH 370/413] fix test --- data/types/base_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/types/base_test.go b/data/types/base_test.go index d6c0fe77af..18dd794cbb 100644 --- a/data/types/base_test.go +++ b/data/types/base_test.go @@ -1006,7 +1006,7 @@ var _ = Describe("Base", func() { Context("GetLegacyTimeField", func() { It("returns expected legacy field details", func() { - t := time.Date(2015, time.July, 31, 23, 59, 59, 999999999, time.UTC) + t, _ := time.Parse(time.RFC3339Nano, "2015-07-31T23:59:59.999Z") legacyTimeField := types.GetLegacyTimeField(&t) Expect(legacyTimeField.Name).To(Equal("time")) Expect(*legacyTimeField.Value).To(Equal("2015-07-31T23:59:59.999Z")) From 88727889ca22b1adfea515dae762c59ee7f2aa23 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 1 Aug 2024 17:32:46 +1200 Subject: [PATCH 371/413] updates for DeviceDeactivateHashName with different versions --- .../deduplicator/device_deactivate_hash.go | 98 ++++++++----------- .../device_deactivate_hash_test.go | 53 ++++++++++ data/service/service/standard.go | 5 +- data/types/upload/upload.go | 19 +++- .../utils/data_migration_test.go | 2 +- .../utils/jellyfish_data.go | 2 +- .../verify/upload_blob.sh | 1 + 7 files changed, 120 insertions(+), 60 deletions(-) diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index 56a0c1c74f..d692e2011d 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -18,7 +18,6 @@ const ( ) const DeviceDeactivateHashName = "org.tidepool.deduplicator.device.deactivate.hash" -const DeviceDeactivateLegacyHashName = "org.tidepool.deduplicator.device.deactivate.legacy.hash" var DeviceDeactivateHashDeviceManufacturerDeviceModels = map[string][]string{ "Abbott": {"FreeStyle Libre"}, @@ -27,7 +26,7 @@ var DeviceDeactivateHashDeviceManufacturerDeviceModels = map[string][]string{ "Trividia Health": {"TRUE METRIX", "TRUE METRIX AIR", "TRUE METRIX GO"}, } -var DeviceDeactivateLegacyHasheManufacturerDeviceModels = map[string][]string{ +var DeviceDeactivateLegacyHashManufacturerDeviceModels = map[string][]string{ "Arkray": {"GlucocardExpression"}, "Bayer": {"Contour Next Link", "Contour Next Link 2.4", "Contour Next", "Contour USB", "Contour Next USB", "Contour Next One", "Contour", "Contour Next EZ", "Contour Plus", "Contour Plus Blue"}, "Dexcom": {"G5 touchscreen receiver", "G6 touchscreen receiver"}, @@ -44,7 +43,7 @@ type DeviceDeactivateHash struct { } func NewDeviceDeactivateLegacyHash() (*DeviceDeactivateHash, error) { - base, err := NewBase(DeviceDeactivateLegacyHashName, "0.0.0") + base, err := NewBase(DeviceDeactivateHashName, "0.0.0") if err != nil { return nil, err } @@ -54,15 +53,6 @@ func NewDeviceDeactivateLegacyHash() (*DeviceDeactivateHash, error) { }, nil } -func (d *DeviceDeactivateHash) getHashType() (HashType, error) { - if d.name == DeviceDeactivateHashName { - return PlatformHash, nil - } else if d.name == DeviceDeactivateLegacyHashName { - return LegacyHash, nil - } - return 0, errors.New("unknown hash type") -} - func NewDeviceDeactivateHash() (*DeviceDeactivateHash, error) { base, err := NewBase(DeviceDeactivateHashName, "1.1.0") if err != nil { @@ -74,61 +64,62 @@ func NewDeviceDeactivateHash() (*DeviceDeactivateHash, error) { }, nil } -func (d *DeviceDeactivateHash) New(dataSet *dataTypesUpload.Upload) (bool, error) { - if dataSet == nil { - return false, errors.New("data set is missing") - } - - if !dataSet.HasDataSetTypeNormal() { - return false, nil - } - if dataSet.DeviceID == nil { - return false, nil - } - - if dataSet.HasDeduplicatorName() { - return d.Get(dataSet) - } - - if dataSet.DeviceManufacturers == nil || dataSet.DeviceModel == nil { - return false, nil - } - - hasher, err := d.getHashType() - - if err != nil { - return false, err - } - if hasher == PlatformHash { +func isManufacturerDeviceModelMatch(dataSet *dataTypesUpload.Upload) (bool, HashType) { + if dataSet.DeviceManufacturers != nil && dataSet.DeviceModel != nil { + // legacy match first for _, deviceManufacturer := range *dataSet.DeviceManufacturers { - if allowedDeviceModels, found := DeviceDeactivateHashDeviceManufacturerDeviceModels[deviceManufacturer]; found { + if allowedDeviceModels, found := DeviceDeactivateLegacyHashManufacturerDeviceModels[deviceManufacturer]; found { for _, allowedDeviceModel := range allowedDeviceModels { if allowedDeviceModel == *dataSet.DeviceModel { - return true, nil + return true, LegacyHash } } } } - } else if hasher == LegacyHash { + // fall back to current for _, deviceManufacturer := range *dataSet.DeviceManufacturers { - if allowedDeviceModels, found := DeviceDeactivateLegacyHasheManufacturerDeviceModels[deviceManufacturer]; found { + if allowedDeviceModels, found := DeviceDeactivateHashDeviceManufacturerDeviceModels[deviceManufacturer]; found { for _, allowedDeviceModel := range allowedDeviceModels { if allowedDeviceModel == *dataSet.DeviceModel { - return true, nil + return true, PlatformHash } } } } } + return false, 0 +} - return false, nil +func (d *DeviceDeactivateHash) New(dataSet *dataTypesUpload.Upload) (bool, error) { + if dataSet == nil { + return false, errors.New("data set is missing") + } + if !dataSet.HasDataSetTypeNormal() { + return false, nil + } + if dataSet.DeviceID == nil { + return false, nil + } + if dataSet.HasDeduplicatorName() { + return d.Get(dataSet) + } + deviceMatch, _ := isManufacturerDeviceModelMatch(dataSet) + return deviceMatch, nil } func (d *DeviceDeactivateHash) Get(dataSet *dataTypesUpload.Upload) (bool, error) { + // NOTE: check legacy first then fallback to other matches + if dataSet == nil { + return false, errors.New("data set is missing") + } + + if dataSet.HasDeduplicatorNameDeviceMatch(DeviceDeactivateHashName, DeviceDeactivateLegacyHashManufacturerDeviceModels) { + return true, nil + } + if found, err := d.Base.Get(dataSet); err != nil || found { return found, err } - return dataSet.HasDeduplicatorNameMatch("org.tidepool.hash-deactivate-old"), nil // TODO: DEPRECATED } @@ -146,17 +137,14 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore return errors.New("data set data is missing") } - hasher, err := d.getHashType() - - if err != nil { - return err - } - - if err := AssignDataSetDataIdentityHashes(dataSetData, hasher); err != nil { - return err + if match, hasher := isManufacturerDeviceModelMatch(dataSet); !match { + return errors.New("data set doesn't match") + } else { + if err := AssignDataSetDataIdentityHashes(dataSetData, hasher); err != nil { + return err + } + return d.Base.AddData(ctx, repository, dataSet, dataSetData) } - - return d.Base.AddData(ctx, repository, dataSet, dataSetData) } func (d *DeviceDeactivateHash) Close(ctx context.Context, repository dataStore.DataRepository, dataSet *dataTypesUpload.Upload) error { diff --git a/data/deduplicator/deduplicator/device_deactivate_hash_test.go b/data/deduplicator/deduplicator/device_deactivate_hash_test.go index eb7645df41..7b61ce1450 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash_test.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash_test.go @@ -64,6 +64,52 @@ var _ = Describe("DeviceDeactivateHash", func() { Expect(deduplicator.New(dataSet)).To(BeFalse()) }) + It("returns false when the deduplicator name does not match", func() { + dataSet.Deduplicator.Name = pointer.FromString(netTest.RandomReverseDomain()) + Expect(deduplicator.New(dataSet)).To(BeFalse()) + }) + + DescribeTable("returns true when", + func(deviceManufacturer string, deviceModel string) { + dataSet.DeviceManufacturers = pointer.FromStringArray([]string{deviceManufacturer}) + dataSet.DeviceModel = pointer.FromString(deviceModel) + Expect(deduplicator.New(dataSet)).To(BeTrue()) + }, + Entry("is Abbott FreeStyle Libre", "Abbott", "FreeStyle Libre"), + Entry("is LifeScan OneTouch Ultra 2", "LifeScan", "OneTouch Ultra 2"), + Entry("is LifeScan OneTouch UltraMini", "LifeScan", "OneTouch UltraMini"), + Entry("is LifeScan Verio", "LifeScan", "Verio"), + Entry("is LifeScan Verio Flex", "LifeScan", "Verio Flex"), + Entry("is Medtronic 523", "Medtronic", "523"), + Entry("is Medtronic 523K", "Medtronic", "523K"), + Entry("is Medtronic 551", "Medtronic", "551"), + Entry("is Medtronic 554", "Medtronic", "554"), + Entry("is Medtronic 723", "Medtronic", "723"), + Entry("is Medtronic 723K", "Medtronic", "723K"), + Entry("is Medtronic 751", "Medtronic", "751"), + Entry("is Medtronic 754", "Medtronic", "754"), + Entry("is Medtronic 1510", "Medtronic", "1510"), + Entry("is Medtronic 1510K", "Medtronic", "1510K"), + Entry("is Medtronic 1511", "Medtronic", "1511"), + Entry("is Medtronic 1512", "Medtronic", "1512"), + Entry("is Medtronic 1580", "Medtronic", "1580"), + Entry("is Medtronic 1581", "Medtronic", "1581"), + Entry("is Medtronic 1582", "Medtronic", "1582"), + Entry("is Medtronic 1710", "Medtronic", "1710"), + Entry("is Medtronic 1710K", "Medtronic", "1710K"), + Entry("is Medtronic 1711", "Medtronic", "1711"), + Entry("is Medtronic 1712", "Medtronic", "1712"), + Entry("is Medtronic 1714", "Medtronic", "1714"), + Entry("is Medtronic 1714K", "Medtronic", "1714K"), + Entry("is Medtronic 1715", "Medtronic", "1715"), + Entry("is Medtronic 1780", "Medtronic", "1780"), + Entry("is Medtronic 1781", "Medtronic", "1781"), + Entry("is Medtronic 1782", "Medtronic", "1782"), + Entry("is Trividia Health TRUE METRIX", "Trividia Health", "TRUE METRIX"), + Entry("is Trividia Health TRUE METRIX AIR", "Trividia Health", "TRUE METRIX AIR"), + Entry("is Trividia Health TRUE METRIX GO", "Trividia Health", "TRUE METRIX GO"), + ) + dataSetTypeAssertions := func() { It("returns false when the deduplicator name does not match", func() { dataSet.Deduplicator.Name = pointer.FromString(netTest.RandomReverseDomain()) @@ -213,6 +259,13 @@ var _ = Describe("DeviceDeactivateHash", func() { dataSet.Deduplicator.Name = pointer.FromString("org.tidepool.hash-deactivate-old") Expect(deduplicator.Get(dataSet)).To(BeTrue()) }) + + It("returns true when the deduplicator name matches and legacy id device and model", func() { + dataSet.Deduplicator.Name = pointer.FromString(dataDeduplicatorDeduplicator.DeviceDeactivateHashName) + dataSet.DeviceManufacturers = pointer.FromStringArray([]string{"Tandem"}) + dataSet.DeviceModel = pointer.FromString("1002717") + Expect(deduplicator.Get(dataSet)).To(BeTrue()) + }) }) Context("with context and repository", func() { diff --git a/data/service/service/standard.go b/data/service/service/standard.go index a10c296260..378610ada2 100644 --- a/data/service/service/standard.go +++ b/data/service/service/standard.go @@ -238,11 +238,12 @@ func (s *Standard) initializeDataDeduplicatorFactory() error { s.Logger().Debug("Creating data deduplicator factory") deduplicators := []dataDeduplicatorFactory.Deduplicator{ - deviceDeactivateHashDeduplicator, + deviceDeactivateLegacyHashDeduplicator, deviceTruncateDataSetDeduplicator, dataSetDeleteOriginDeduplicator, noneDeduplicator, - deviceDeactivateLegacyHashDeduplicator, + //default + deviceDeactivateHashDeduplicator, } factory, err := dataDeduplicatorFactory.New(deduplicators) diff --git a/data/types/upload/upload.go b/data/types/upload/upload.go index 04a3be05ff..d7a03d23c6 100644 --- a/data/types/upload/upload.go +++ b/data/types/upload/upload.go @@ -213,5 +213,22 @@ func (u *Upload) HasDeduplicatorName() bool { } func (u *Upload) HasDeduplicatorNameMatch(name string) bool { - return u.Deduplicator != nil && u.Deduplicator.HasNameMatch(name) + return u.HasDeduplicatorName() && u.Deduplicator.HasNameMatch(name) +} + +func (u *Upload) HasDeduplicatorNameDeviceMatch(name string, deviceModels map[string][]string) bool { + if u.HasDeduplicatorNameMatch(name) { + if u.DeviceManufacturers != nil && u.DeviceModel != nil { + for _, deviceManufacturer := range *u.DeviceManufacturers { + if allowedDeviceModels, found := deviceModels[deviceManufacturer]; found { + for _, allowedDeviceModel := range allowedDeviceModels { + if allowedDeviceModel == *u.DeviceModel { + return true + } + } + } + } + } + } + return false } diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration_test.go b/migrations/20231128_jellyfish_migration/utils/data_migration_test.go index bdd527e025..860c3ee0c4 100644 --- a/migrations/20231128_jellyfish_migration/utils/data_migration_test.go +++ b/migrations/20231128_jellyfish_migration/utils/data_migration_test.go @@ -145,7 +145,7 @@ var _ = Describe("back-37", func() { for _, item := range migrated { Expect(item).Should(HaveKey("_deduplicator")) Expect(item["_deduplicator"]).Should(HaveLen(2)) - Expect(item["_deduplicator"]).Should(HaveKeyWithValue("name", deduplicator.DeviceDeactivateLegacyHashName)) + Expect(item["_deduplicator"]).Should(HaveKeyWithValue("name", deduplicator.DeviceDeactivateHashName)) Expect(item["_deduplicator"]).Should(HaveKeyWithValue("version", "0.0.0")) } }) diff --git a/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go b/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go index 1c1954cb34..bb1cc437b7 100644 --- a/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go +++ b/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go @@ -163,7 +163,7 @@ var JellyfishUploadQueryFn = func(m *DataMigration) bool { m.SetUpdates(UpdateData{ Filter: bson.M{"_id": result.ID}, ItemID: result.ID, - Apply: []bson.M{{"$set": bson.M{"_deduplicator": bson.M{"name": deduplicator.DeviceDeactivateLegacyHashName, "version": "0.0.0"}}}}, + Apply: []bson.M{{"$set": bson.M{"_deduplicator": bson.M{"name": deduplicator.DeviceDeactivateHashName, "version": "0.0.0"}}}}, }) count++ m.SetLastProcessed(result.ID) diff --git a/migrations/20231128_jellyfish_migration/verify/upload_blob.sh b/migrations/20231128_jellyfish_migration/verify/upload_blob.sh index 7451909e6f..399f5562d3 100644 --- a/migrations/20231128_jellyfish_migration/verify/upload_blob.sh +++ b/migrations/20231128_jellyfish_migration/verify/upload_blob.sh @@ -31,6 +31,7 @@ output='not yet run' if [[ "$BLOB_FILE" =~ .*"tandem".* ]]; then output=$(node -r @babel/register lib/drivers/tandem/cli/loader.js loader.js -f $BLOB_FILE -u $USER_EMAIL -p $USER_PW) + echo "$output" echo "$output" | grep -q 'upload.toPlatform: all good' && SUCCESS=true else output=$(node -r @babel/register lib/drivers/insulet/cli/ibf_loader.js ibf_loader.js -f $BLOB_FILE -u $USER_EMAIL -p $USER_PW) From 275cf7a2b5b630fae4042f6b3ddff5fe0c321b66 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 2 Aug 2024 10:52:31 +1200 Subject: [PATCH 372/413] refine setting of DeviceDeactivateHashVersion --- .../deduplicator/device_deactivate_hash.go | 48 +++++++------- data/deduplicator/deduplicator/hash.go | 20 +++--- data/deduplicator/deduplicator/hash_test.go | 64 +++++++++++++++++-- data/service/service/standard.go | 1 - data/types/upload/upload.go | 17 ----- 5 files changed, 93 insertions(+), 57 deletions(-) diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index d692e2011d..fc5ab386b3 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -9,12 +9,12 @@ import ( "github.com/tidepool-org/platform/errors" ) -type HashType int +type DeviceDeactivateHashVersion string const ( - _ HashType = iota - PlatformHash - LegacyHash + UnkownVersion DeviceDeactivateHashVersion = "" + CurrentVersion DeviceDeactivateHashVersion = "1.1.0" + LegacyVersion DeviceDeactivateHashVersion = "0.0.0" ) const DeviceDeactivateHashName = "org.tidepool.deduplicator.device.deactivate.hash" @@ -43,7 +43,7 @@ type DeviceDeactivateHash struct { } func NewDeviceDeactivateLegacyHash() (*DeviceDeactivateHash, error) { - base, err := NewBase(DeviceDeactivateHashName, "0.0.0") + base, err := NewBase(DeviceDeactivateHashName, string(LegacyVersion)) if err != nil { return nil, err } @@ -54,7 +54,7 @@ func NewDeviceDeactivateLegacyHash() (*DeviceDeactivateHash, error) { } func NewDeviceDeactivateHash() (*DeviceDeactivateHash, error) { - base, err := NewBase(DeviceDeactivateHashName, "1.1.0") + base, err := NewBase(DeviceDeactivateHashName, string(CurrentVersion)) if err != nil { return nil, err } @@ -64,30 +64,39 @@ func NewDeviceDeactivateHash() (*DeviceDeactivateHash, error) { }, nil } -func isManufacturerDeviceModelMatch(dataSet *dataTypesUpload.Upload) (bool, HashType) { +func getDeviceDeactivateHashVersion(dataSet *dataTypesUpload.Upload) DeviceDeactivateHashVersion { + if dataSet.Deduplicator != nil { + if dataSet.Deduplicator.Name != nil && dataSet.Deduplicator.Version != nil { + if *dataSet.Deduplicator.Name == DeviceDeactivateHashName { + if *dataSet.Deduplicator.Version == string(LegacyVersion) { + return LegacyVersion + } else if *dataSet.Deduplicator.Version == string(CurrentVersion) { + return CurrentVersion + } + } + } + } if dataSet.DeviceManufacturers != nil && dataSet.DeviceModel != nil { - // legacy match first for _, deviceManufacturer := range *dataSet.DeviceManufacturers { if allowedDeviceModels, found := DeviceDeactivateLegacyHashManufacturerDeviceModels[deviceManufacturer]; found { for _, allowedDeviceModel := range allowedDeviceModels { if allowedDeviceModel == *dataSet.DeviceModel { - return true, LegacyHash + return LegacyVersion } } } } - // fall back to current for _, deviceManufacturer := range *dataSet.DeviceManufacturers { if allowedDeviceModels, found := DeviceDeactivateHashDeviceManufacturerDeviceModels[deviceManufacturer]; found { for _, allowedDeviceModel := range allowedDeviceModels { if allowedDeviceModel == *dataSet.DeviceModel { - return true, PlatformHash + return CurrentVersion } } } } } - return false, 0 + return UnkownVersion } func (d *DeviceDeactivateHash) New(dataSet *dataTypesUpload.Upload) (bool, error) { @@ -103,8 +112,7 @@ func (d *DeviceDeactivateHash) New(dataSet *dataTypesUpload.Upload) (bool, error if dataSet.HasDeduplicatorName() { return d.Get(dataSet) } - deviceMatch, _ := isManufacturerDeviceModelMatch(dataSet) - return deviceMatch, nil + return getDeviceDeactivateHashVersion(dataSet) != UnkownVersion, nil } func (d *DeviceDeactivateHash) Get(dataSet *dataTypesUpload.Upload) (bool, error) { @@ -113,7 +121,7 @@ func (d *DeviceDeactivateHash) Get(dataSet *dataTypesUpload.Upload) (bool, error return false, errors.New("data set is missing") } - if dataSet.HasDeduplicatorNameDeviceMatch(DeviceDeactivateHashName, DeviceDeactivateLegacyHashManufacturerDeviceModels) { + if getDeviceDeactivateHashVersion(dataSet) == LegacyVersion { return true, nil } @@ -137,14 +145,10 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore return errors.New("data set data is missing") } - if match, hasher := isManufacturerDeviceModelMatch(dataSet); !match { - return errors.New("data set doesn't match") - } else { - if err := AssignDataSetDataIdentityHashes(dataSetData, hasher); err != nil { - return err - } - return d.Base.AddData(ctx, repository, dataSet, dataSetData) + if err := AssignDataSetDataIdentityHashes(dataSetData, getDeviceDeactivateHashVersion(dataSet)); err != nil { + return err } + return d.Base.AddData(ctx, repository, dataSet, dataSetData) } func (d *DeviceDeactivateHash) Close(ctx context.Context, repository dataStore.DataRepository, dataSet *dataTypesUpload.Upload) error { diff --git a/data/deduplicator/deduplicator/hash.go b/data/deduplicator/deduplicator/hash.go index 740eeff8f6..738996bd9b 100644 --- a/data/deduplicator/deduplicator/hash.go +++ b/data/deduplicator/deduplicator/hash.go @@ -13,24 +13,24 @@ import ( "github.com/tidepool-org/platform/pointer" ) -func AssignDataSetDataIdentityHashes(dataSetData data.Data, hasher HashType) error { +func AssignDataSetDataIdentityHashes(dataSetData data.Data, version DeviceDeactivateHashVersion) error { for _, dataSetDatum := range dataSetData { var hash string - if hasher == PlatformHash { - fields, err := dataSetDatum.IdentityFields() + if version == LegacyVersion { + fields, err := dataSetDatum.LegacyIdentityFields() if err != nil { - return errors.Wrap(err, "unable to gather identity fields for datum") + return errors.Wrap(err, "unable to gather legacy identity fields for datum") } - hash, err = GenerateIdentityHash(fields) + hash, err = GenerateLegacyIdentityHash(fields) if err != nil { - return errors.Wrap(err, "unable to generate identity hash for datum") + return errors.Wrap(err, "unable to generate legacy identity hash for datum") } - } else if hasher == LegacyHash { - fields, err := dataSetDatum.LegacyIdentityFields() + } else { + fields, err := dataSetDatum.IdentityFields() if err != nil { - return errors.Wrap(err, "unable to gather legacy identity fields for datum") + return errors.Wrap(err, "unable to gather identity fields for datum") } - hash, err = GenerateLegacyIdentityHash(fields) + hash, err = GenerateIdentityHash(fields) if err != nil { return errors.Wrap(err, "unable to generate identity hash for datum") } diff --git a/data/deduplicator/deduplicator/hash_test.go b/data/deduplicator/deduplicator/hash_test.go index e04efb709e..0f4c7f1420 100644 --- a/data/deduplicator/deduplicator/hash_test.go +++ b/data/deduplicator/deduplicator/hash_test.go @@ -34,35 +34,67 @@ var _ = Describe("Hash", func() { }) It("returns successfully when the data is nil", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(nil, dataDeduplicatorDeduplicator.PlatformHash)).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(nil, dataDeduplicatorDeduplicator.CurrentVersion)).To(Succeed()) }) It("returns successfully when there is no data", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(data.Data{}, dataDeduplicatorDeduplicator.PlatformHash)).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(nil, dataDeduplicatorDeduplicator.LegacyVersion)).To(Succeed()) + }) + + It("returns successfully when there is no data", func() { + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(data.Data{}, dataDeduplicatorDeduplicator.CurrentVersion)).To(Succeed()) + }) + + It("returns successfully when there is no data", func() { + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(data.Data{}, dataDeduplicatorDeduplicator.LegacyVersion)).To(Succeed()) }) It("returns an error when any datum returns an error getting identity fields", func() { dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: nil, Error: errors.New("test error")}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.PlatformHash)).To(MatchError("unable to gather identity fields for datum; test error")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.CurrentVersion)).To(MatchError("unable to gather identity fields for datum; test error")) + }) + + It("returns an error when any datum returns an error getting legacy identity fields", func() { + dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} + dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: nil, Error: errors.New("test error")}} + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.LegacyVersion)).To(MatchError("unable to gather legacy identity fields for datum; test error")) }) It("returns an error when any datum returns no identity fields", func() { dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: nil, Error: nil}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.PlatformHash)).To(MatchError("unable to generate identity hash for datum; identity fields are missing")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.CurrentVersion)).To(MatchError("unable to generate identity hash for datum; identity fields are missing")) + }) + + It("returns an error when any datum returns no legacy identity fields", func() { + dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} + dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: nil, Error: nil}} + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.LegacyVersion)).To(MatchError("unable to generate legacy identity hash for datum; identity fields are missing")) }) It("returns an error when any datum returns empty identity fields", func() { dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{}, Error: nil}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.PlatformHash)).To(MatchError("unable to generate identity hash for datum; identity fields are missing")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.CurrentVersion)).To(MatchError("unable to generate identity hash for datum; identity fields are missing")) + }) + + It("returns an error when any datum returns empty legacy identity fields", func() { + dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} + dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{}, Error: nil}} + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.LegacyVersion)).To(MatchError("unable to generate legacy identity hash for datum; identity fields are missing")) }) It("returns an error when any datum returns any empty identity fields", func() { dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), ""}, Error: nil}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.PlatformHash)).To(MatchError("unable to generate identity hash for datum; identity field is empty")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.CurrentVersion)).To(MatchError("unable to generate identity hash for datum; identity field is empty")) + }) + + It("returns an error when any datum returns any empty legacy identity fields", func() { + dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} + dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), ""}, Error: nil}} + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.LegacyVersion)).To(MatchError("unable to generate legacy identity hash for datum; identity field is empty")) }) Context("with identity fields", func() { @@ -79,7 +111,25 @@ var _ = Describe("Hash", func() { }) It("returns successfully", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.PlatformHash)).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.CurrentVersion)).To(Succeed()) + }) + }) + + Context("with legacy identity fields", func() { + BeforeEach(func() { + dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{"test", "0"}, Error: nil}} + dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{"test", "1"}, Error: nil}} + dataSetDataTest[2].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{"test", "2"}, Error: nil}} + }) + + AfterEach(func() { + Expect(dataSetDataTest[0].DeduplicatorDescriptorValue).To(Equal(&data.DeduplicatorDescriptor{Hash: pointer.FromString("1i2gupee95mf7ooatr0cveo9qr6dt2i6")})) + Expect(dataSetDataTest[1].DeduplicatorDescriptorValue).To(Equal(&data.DeduplicatorDescriptor{Hash: pointer.FromString("f0mq6bk3d79aua8lre8ti8bosqkaf10d")})) + Expect(dataSetDataTest[2].DeduplicatorDescriptorValue).To(Equal(&data.DeduplicatorDescriptor{Hash: pointer.FromString("sknnju4it96cqsbcmuh3g1navg1kdvp5")})) + }) + + It("returns successfully", func() { + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.LegacyVersion)).To(Succeed()) }) }) }) diff --git a/data/service/service/standard.go b/data/service/service/standard.go index 378610ada2..85b25148fb 100644 --- a/data/service/service/standard.go +++ b/data/service/service/standard.go @@ -242,7 +242,6 @@ func (s *Standard) initializeDataDeduplicatorFactory() error { deviceTruncateDataSetDeduplicator, dataSetDeleteOriginDeduplicator, noneDeduplicator, - //default deviceDeactivateHashDeduplicator, } diff --git a/data/types/upload/upload.go b/data/types/upload/upload.go index d7a03d23c6..b3b4780a95 100644 --- a/data/types/upload/upload.go +++ b/data/types/upload/upload.go @@ -215,20 +215,3 @@ func (u *Upload) HasDeduplicatorName() bool { func (u *Upload) HasDeduplicatorNameMatch(name string) bool { return u.HasDeduplicatorName() && u.Deduplicator.HasNameMatch(name) } - -func (u *Upload) HasDeduplicatorNameDeviceMatch(name string, deviceModels map[string][]string) bool { - if u.HasDeduplicatorNameMatch(name) { - if u.DeviceManufacturers != nil && u.DeviceModel != nil { - for _, deviceManufacturer := range *u.DeviceManufacturers { - if allowedDeviceModels, found := deviceModels[deviceManufacturer]; found { - for _, allowedDeviceModel := range allowedDeviceModels { - if allowedDeviceModel == *u.DeviceModel { - return true - } - } - } - } - } - } - return false -} From 5f6398ce1d0687652fa3551b8bab4a0b897332c0 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 2 Aug 2024 13:22:42 +1200 Subject: [PATCH 373/413] no-op on base LegacyIdentityFields --- data/types/base.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/types/base.go b/data/types/base.go index 6cc8d4be88..078db36c11 100644 --- a/data/types/base.go +++ b/data/types/base.go @@ -297,7 +297,7 @@ func GetLegacyIDFields(fields ...LegacyIDField) ([]string, error) { } func (b *Base) LegacyIdentityFields() ([]string, error) { - return nil, errors.New("function must be implemented on data type") + return []string{}, nil } func (b *Base) GetOrigin() *origin.Origin { From ed43af9a60d4576de413089dc5faac78b194a27b Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 2 Aug 2024 13:48:44 +1200 Subject: [PATCH 374/413] fix test --- data/types/base_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/types/base_test.go b/data/types/base_test.go index 18dd794cbb..9b48b217b4 100644 --- a/data/types/base_test.go +++ b/data/types/base_test.go @@ -974,9 +974,9 @@ var _ = Describe("Base", func() { datum = dataTypesTest.RandomBase() }) - It("returns error if not implemented", func() { + It("returns empty", func() { legacyIDFields, err := datum.LegacyIdentityFields() - Expect(err).To(MatchError("function must be implemented on data type")) + Expect(err).To(BeNil()) Expect(legacyIDFields).To(BeEmpty()) }) From 0a5c1ccfa1feaacfbaaa6468a0d09ac52d8705fa Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 2 Aug 2024 15:29:52 +1200 Subject: [PATCH 375/413] LegacyIdentityFields returns base fields --- data/types/base.go | 17 ++++++++++++++++- data/types/base_test.go | 5 +++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/data/types/base.go b/data/types/base.go index 078db36c11..4bbd78ecb1 100644 --- a/data/types/base.go +++ b/data/types/base.go @@ -297,7 +297,22 @@ func GetLegacyIDFields(fields ...LegacyIDField) ([]string, error) { } func (b *Base) LegacyIdentityFields() ([]string, error) { - return []string{}, nil + if b.Type == "" { + return nil, errors.New("type is empty") + } + if b.DeviceID == nil { + return nil, errors.New("device id is missing") + } + if *b.DeviceID == "" { + return nil, errors.New("device id is empty") + } + if b.Time == nil { + return nil, errors.New("time is missing") + } + if (*b.Time).IsZero() { + return nil, errors.New("time is empty") + } + return []string{b.Type, *b.DeviceID, (*b.Time).Format(TimeFormat)}, nil } func (b *Base) GetOrigin() *origin.Origin { diff --git a/data/types/base_test.go b/data/types/base_test.go index 9b48b217b4..c6dcc541b2 100644 --- a/data/types/base_test.go +++ b/data/types/base_test.go @@ -974,10 +974,11 @@ var _ = Describe("Base", func() { datum = dataTypesTest.RandomBase() }) - It("returns empty", func() { + It("returns the expected identity fields", func() { legacyIDFields, err := datum.LegacyIdentityFields() Expect(err).To(BeNil()) - Expect(legacyIDFields).To(BeEmpty()) + Expect(legacyIDFields).ToNot(BeEmpty()) + Expect(legacyIDFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(ExpectedTimeFormat)})) }) Context("GetLegacyIDFields", func() { From fe8a85a34d84ea49403cac1fac4af8d261ccd09c Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 5 Aug 2024 10:52:37 +1200 Subject: [PATCH 376/413] sorting out LegacyIdentityFields error --- data/deduplicator/deduplicator/hash.go | 9 +++- data/deduplicator/deduplicator/hash_test.go | 53 +++++++++++++++++++-- data/types/base.go | 17 +------ data/types/base_test.go | 5 +- 4 files changed, 59 insertions(+), 25 deletions(-) diff --git a/data/deduplicator/deduplicator/hash.go b/data/deduplicator/deduplicator/hash.go index 738996bd9b..3ab79a2789 100644 --- a/data/deduplicator/deduplicator/hash.go +++ b/data/deduplicator/deduplicator/hash.go @@ -6,6 +6,7 @@ import ( "encoding/base32" "encoding/base64" "fmt" + "log" "strings" "github.com/tidepool-org/platform/data" @@ -19,11 +20,15 @@ func AssignDataSetDataIdentityHashes(dataSetData data.Data, version DeviceDeacti if version == LegacyVersion { fields, err := dataSetDatum.LegacyIdentityFields() if err != nil { - return errors.Wrap(err, "unable to gather legacy identity fields for datum") + return errors.Wrapf(err, "unable to gather legacy identity fields for datum %T", dataSetDatum) + } + if dataSetDatum.GetType() == "smbg" { + log.Printf("SMBG LegacyIdentityFields are [%v]", fields) } hash, err = GenerateLegacyIdentityHash(fields) + if err != nil { - return errors.Wrap(err, "unable to generate legacy identity hash for datum") + return errors.Wrapf(err, "unable to generate legacy identity hash for datum %T", dataSetDatum) } } else { fields, err := dataSetDatum.IdentityFields() diff --git a/data/deduplicator/deduplicator/hash_test.go b/data/deduplicator/deduplicator/hash_test.go index 0f4c7f1420..cfefc272a5 100644 --- a/data/deduplicator/deduplicator/hash_test.go +++ b/data/deduplicator/deduplicator/hash_test.go @@ -6,7 +6,13 @@ import ( "github.com/tidepool-org/platform/data" dataDeduplicatorDeduplicator "github.com/tidepool-org/platform/data/deduplicator/deduplicator" + "github.com/tidepool-org/platform/structure" + "github.com/tidepool-org/platform/test" + + dataNormalizer "github.com/tidepool-org/platform/data/normalizer" dataTest "github.com/tidepool-org/platform/data/test" + "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" + dataTypesBloodGlucoseTest "github.com/tidepool-org/platform/data/types/blood/glucose/test" "github.com/tidepool-org/platform/errors" "github.com/tidepool-org/platform/pointer" userTest "github.com/tidepool-org/platform/user/test" @@ -57,8 +63,10 @@ var _ = Describe("Hash", func() { It("returns an error when any datum returns an error getting legacy identity fields", func() { dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} + dataSetDataTest[0].GetTypeOutputs = []string{"test-type"} dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: nil, Error: errors.New("test error")}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.LegacyVersion)).To(MatchError("unable to gather legacy identity fields for datum; test error")) + dataSetDataTest[1].GetTypeOutputs = []string{"test-type"} + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.LegacyVersion)).To(MatchError("unable to gather legacy identity fields for datum *test.Datum; test error")) }) It("returns an error when any datum returns no identity fields", func() { @@ -69,8 +77,10 @@ var _ = Describe("Hash", func() { It("returns an error when any datum returns no legacy identity fields", func() { dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} + dataSetDataTest[0].GetTypeOutputs = []string{"test-type"} dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: nil, Error: nil}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.LegacyVersion)).To(MatchError("unable to generate legacy identity hash for datum; identity fields are missing")) + dataSetDataTest[1].GetTypeOutputs = []string{"test-type"} + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.LegacyVersion)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity fields are missing")) }) It("returns an error when any datum returns empty identity fields", func() { @@ -81,8 +91,10 @@ var _ = Describe("Hash", func() { It("returns an error when any datum returns empty legacy identity fields", func() { dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} + dataSetDataTest[0].GetTypeOutputs = []string{"test-type"} dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{}, Error: nil}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.LegacyVersion)).To(MatchError("unable to generate legacy identity hash for datum; identity fields are missing")) + dataSetDataTest[1].GetTypeOutputs = []string{"test-type"} + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.LegacyVersion)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity fields are missing")) }) It("returns an error when any datum returns any empty identity fields", func() { @@ -93,8 +105,10 @@ var _ = Describe("Hash", func() { It("returns an error when any datum returns any empty legacy identity fields", func() { dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} + dataSetDataTest[0].GetTypeOutputs = []string{"test-type"} dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), ""}, Error: nil}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.LegacyVersion)).To(MatchError("unable to generate legacy identity hash for datum; identity field is empty")) + dataSetDataTest[1].GetTypeOutputs = []string{"test-type"} + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.LegacyVersion)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity field is empty")) }) Context("with identity fields", func() { @@ -118,8 +132,11 @@ var _ = Describe("Hash", func() { Context("with legacy identity fields", func() { BeforeEach(func() { dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{"test", "0"}, Error: nil}} + dataSetDataTest[0].GetTypeOutputs = []string{"test-type"} dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{"test", "1"}, Error: nil}} + dataSetDataTest[1].GetTypeOutputs = []string{"test-type"} dataSetDataTest[2].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{"test", "2"}, Error: nil}} + dataSetDataTest[2].GetTypeOutputs = []string{"test-type"} }) AfterEach(func() { @@ -132,6 +149,34 @@ var _ = Describe("Hash", func() { Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.LegacyVersion)).To(Succeed()) }) }) + + Context("with legacy identity fields", func() { + var smbgData data.Data + BeforeEach(func() { + var newSMBG = func() data.Datum { + datum := selfmonitored.New() + datum.Glucose = *dataTypesBloodGlucoseTest.NewGlucose(pointer.FromString("mg/dl")) + datum.Type = "smbg" + datum.Value = pointer.FromFloat64(150) + datum.SubType = pointer.FromString(test.RandomStringFromArray(selfmonitored.SubTypes())) + + normalizer := dataNormalizer.New() + Expect(normalizer).ToNot(BeNil()) + datum.Normalize(normalizer.WithOrigin(structure.OriginExternal)) + return datum + } + + for i := 0; i < 10; i++ { + smbgData = append(smbgData, newSMBG()) + } + + }) + + It("returns successfully", func() { + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(smbgData, dataDeduplicatorDeduplicator.LegacyVersion)).To(Succeed()) + }) + + }) }) Context("GenerateIdentityHash", func() { diff --git a/data/types/base.go b/data/types/base.go index 4bbd78ecb1..078db36c11 100644 --- a/data/types/base.go +++ b/data/types/base.go @@ -297,22 +297,7 @@ func GetLegacyIDFields(fields ...LegacyIDField) ([]string, error) { } func (b *Base) LegacyIdentityFields() ([]string, error) { - if b.Type == "" { - return nil, errors.New("type is empty") - } - if b.DeviceID == nil { - return nil, errors.New("device id is missing") - } - if *b.DeviceID == "" { - return nil, errors.New("device id is empty") - } - if b.Time == nil { - return nil, errors.New("time is missing") - } - if (*b.Time).IsZero() { - return nil, errors.New("time is empty") - } - return []string{b.Type, *b.DeviceID, (*b.Time).Format(TimeFormat)}, nil + return []string{}, nil } func (b *Base) GetOrigin() *origin.Origin { diff --git a/data/types/base_test.go b/data/types/base_test.go index c6dcc541b2..6d53232b8f 100644 --- a/data/types/base_test.go +++ b/data/types/base_test.go @@ -974,11 +974,10 @@ var _ = Describe("Base", func() { datum = dataTypesTest.RandomBase() }) - It("returns the expected identity fields", func() { + It("returns the expected empty identity fields", func() { legacyIDFields, err := datum.LegacyIdentityFields() Expect(err).To(BeNil()) - Expect(legacyIDFields).ToNot(BeEmpty()) - Expect(legacyIDFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(ExpectedTimeFormat)})) + Expect(legacyIDFields).To(BeEmpty()) }) Context("GetLegacyIDFields", func() { From 5ddf7eca3c23b75c4bce27a0f1ad250490bb25bc Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 5 Aug 2024 11:52:31 +1200 Subject: [PATCH 377/413] set base LegacyIdentityFields as type, deviceId and time --- data/types/activity/physical/physical.go | 6 +----- data/types/base.go | 17 +++++++++++++++- data/types/base_test.go | 3 ++- data/types/blood/blood.go | 6 +----- data/types/calculator/calculator.go | 4 ++++ data/types/calculator/calculator_test.go | 26 ++++++++++++++++++++++++ data/types/food/food.go | 6 +----- data/types/insulin/insulin.go | 6 +----- 8 files changed, 52 insertions(+), 22 deletions(-) diff --git a/data/types/activity/physical/physical.go b/data/types/activity/physical/physical.go index 1428a91093..4e84ce24ee 100644 --- a/data/types/activity/physical/physical.go +++ b/data/types/activity/physical/physical.go @@ -298,9 +298,5 @@ func (p *Physical) Normalize(normalizer data.Normalizer) { } func (p *Physical) LegacyIdentityFields() ([]string, error) { - return types.GetLegacyIDFields( - types.LegacyIDField{Name: "type", Value: &p.Type}, - types.LegacyIDField{Name: "device id", Value: p.DeviceID}, - types.GetLegacyTimeField(p.Time), - ) + return p.Base.LegacyIdentityFields() } diff --git a/data/types/base.go b/data/types/base.go index 078db36c11..4bbd78ecb1 100644 --- a/data/types/base.go +++ b/data/types/base.go @@ -297,7 +297,22 @@ func GetLegacyIDFields(fields ...LegacyIDField) ([]string, error) { } func (b *Base) LegacyIdentityFields() ([]string, error) { - return []string{}, nil + if b.Type == "" { + return nil, errors.New("type is empty") + } + if b.DeviceID == nil { + return nil, errors.New("device id is missing") + } + if *b.DeviceID == "" { + return nil, errors.New("device id is empty") + } + if b.Time == nil { + return nil, errors.New("time is missing") + } + if (*b.Time).IsZero() { + return nil, errors.New("time is empty") + } + return []string{b.Type, *b.DeviceID, (*b.Time).Format(TimeFormat)}, nil } func (b *Base) GetOrigin() *origin.Origin { diff --git a/data/types/base_test.go b/data/types/base_test.go index 6d53232b8f..ce7f801a61 100644 --- a/data/types/base_test.go +++ b/data/types/base_test.go @@ -977,7 +977,8 @@ var _ = Describe("Base", func() { It("returns the expected empty identity fields", func() { legacyIDFields, err := datum.LegacyIdentityFields() Expect(err).To(BeNil()) - Expect(legacyIDFields).To(BeEmpty()) + Expect(legacyIDFields).ToNot(BeEmpty()) + Expect(legacyIDFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(ExpectedTimeFormat)})) }) Context("GetLegacyIDFields", func() { diff --git a/data/types/blood/blood.go b/data/types/blood/blood.go index 0e699284f0..29a9b358ff 100644 --- a/data/types/blood/blood.go +++ b/data/types/blood/blood.go @@ -47,11 +47,7 @@ func (b *Blood) IdentityFields() ([]string, error) { } func (b *Blood) LegacyIdentityFields() ([]string, error) { - return types.GetLegacyIDFields( - types.LegacyIDField{Name: "type", Value: &b.Type}, - types.LegacyIDField{Name: "device id", Value: b.DeviceID}, - types.GetLegacyTimeField(b.Time), - ) + return b.Base.LegacyIdentityFields() } func (b *Blood) GetRawValueAndUnits() (*float64, *string, error) { diff --git a/data/types/calculator/calculator.go b/data/types/calculator/calculator.go index 70a72178f0..4a5d9e2585 100644 --- a/data/types/calculator/calculator.go +++ b/data/types/calculator/calculator.go @@ -118,6 +118,10 @@ func (c *Calculator) Validate(validator structure.Validator) { } } +func (c *Calculator) LegacyIdentityFields() ([]string, error) { + return c.Base.LegacyIdentityFields() +} + func (c *Calculator) Normalize(normalizer data.Normalizer) { if !normalizer.HasMeta() { normalizer = normalizer.WithMeta(c.Meta()) diff --git a/data/types/calculator/calculator_test.go b/data/types/calculator/calculator_test.go index 4c0fd440d4..f7210c861e 100644 --- a/data/types/calculator/calculator_test.go +++ b/data/types/calculator/calculator_test.go @@ -1,6 +1,8 @@ package calculator_test import ( + "time" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -153,6 +155,30 @@ var _ = Describe("Calculator", func() { Expect(datum.CarbUnits).To(BeNil()) }) }) + Context("LegacyIdentityFields", func() { + var datum *calculator.Calculator + + BeforeEach(func() { + datum = NewCalculator(pointer.FromString("mmol/L")) + }) + + It("returns error if delivery type is empty", func() { + datum.Type = "" + identityFields, err := datum.LegacyIdentityFields() + Expect(err).To(MatchError("type is empty")) + Expect(identityFields).To(BeEmpty()) + }) + + It("returns the expected legacy identity fields", func() { + datum.DeviceID = pointer.FromString("some-device") + t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") + Expect(err).ToNot(HaveOccurred()) + datum.Time = pointer.FromTime(t) + legacyIdentityFields, err := datum.LegacyIdentityFields() + Expect(err).ToNot(HaveOccurred()) + Expect(legacyIdentityFields).To(Equal([]string{"wizard", "some-device", "2023-05-13T15:51:58Z"})) + }) + }) Context("Calculator", func() { Context("Parse", func() { diff --git a/data/types/food/food.go b/data/types/food/food.go index b31018c715..26c47f18be 100644 --- a/data/types/food/food.go +++ b/data/types/food/food.go @@ -106,9 +106,5 @@ func (f *Food) Normalize(normalizer data.Normalizer) { } func (f *Food) LegacyIdentityFields() ([]string, error) { - return types.GetLegacyIDFields( - types.LegacyIDField{Name: "type", Value: &f.Type}, - types.LegacyIDField{Name: "device id", Value: f.DeviceID}, - types.GetLegacyTimeField(f.Time), - ) + return f.Base.LegacyIdentityFields() } diff --git a/data/types/insulin/insulin.go b/data/types/insulin/insulin.go index 83bf185fbe..2a579db308 100644 --- a/data/types/insulin/insulin.go +++ b/data/types/insulin/insulin.go @@ -74,9 +74,5 @@ func (i *Insulin) Normalize(normalizer data.Normalizer) { } func (i *Insulin) LegacyIdentityFields() ([]string, error) { - return types.GetLegacyIDFields( - types.LegacyIDField{Name: "type", Value: &i.Type}, - types.LegacyIDField{Name: "device id", Value: i.DeviceID}, - types.GetLegacyTimeField(i.Time), - ) + return i.Base.LegacyIdentityFields() } From 8a2020887d115d81e0d14470fae007672734fc75 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 5 Aug 2024 16:18:14 +1200 Subject: [PATCH 378/413] modify time format --- data/types/base.go | 5 +++-- data/types/base_test.go | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/data/types/base.go b/data/types/base.go index 4bbd78ecb1..cff87ea0fc 100644 --- a/data/types/base.go +++ b/data/types/base.go @@ -21,6 +21,7 @@ const ( ClockDriftOffsetMaximum = 24 * 60 * 60 * 1000 // TODO: Fix! Limit to reasonable values ClockDriftOffsetMinimum = -24 * 60 * 60 * 1000 // TODO: Fix! Limit to reasonable values DeviceTimeFormat = "2006-01-02T15:04:05" + LegacyDeviceTimeFormat = "2006-01-02T15:04:05.999Z" NoteLengthMaximum = 1000 NotesLengthMaximum = 100 TagLengthMaximum = 100 @@ -278,7 +279,7 @@ func GetLegacyTimeField(t *time.Time) LegacyIDField { return LegacyIDField{Name: "time", Value: &tVal} } - tVal = (*t).Format(TimeFormat) + tVal = (*t).Format(LegacyDeviceTimeFormat) return LegacyIDField{Name: "time", Value: &tVal} } @@ -312,7 +313,7 @@ func (b *Base) LegacyIdentityFields() ([]string, error) { if (*b.Time).IsZero() { return nil, errors.New("time is empty") } - return []string{b.Type, *b.DeviceID, (*b.Time).Format(TimeFormat)}, nil + return []string{b.Type, *b.DeviceID, (*b.Time).Format(LegacyDeviceTimeFormat)}, nil } func (b *Base) GetOrigin() *origin.Origin { diff --git a/data/types/base_test.go b/data/types/base_test.go index ce7f801a61..b4cb46e4ac 100644 --- a/data/types/base_test.go +++ b/data/types/base_test.go @@ -978,7 +978,7 @@ var _ = Describe("Base", func() { legacyIDFields, err := datum.LegacyIdentityFields() Expect(err).To(BeNil()) Expect(legacyIDFields).ToNot(BeEmpty()) - Expect(legacyIDFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(ExpectedTimeFormat)})) + Expect(legacyIDFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyDeviceTimeFormat)})) }) Context("GetLegacyIDFields", func() { From e6dce6ca013aaba78b1e7b1a56458405a6f40368 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 5 Aug 2024 17:08:41 +1200 Subject: [PATCH 379/413] fix format to keep trailing zeros --- data/types/base.go | 6 +++--- data/types/base_test.go | 10 +++++++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/data/types/base.go b/data/types/base.go index cff87ea0fc..1a05b0b7aa 100644 --- a/data/types/base.go +++ b/data/types/base.go @@ -21,7 +21,7 @@ const ( ClockDriftOffsetMaximum = 24 * 60 * 60 * 1000 // TODO: Fix! Limit to reasonable values ClockDriftOffsetMinimum = -24 * 60 * 60 * 1000 // TODO: Fix! Limit to reasonable values DeviceTimeFormat = "2006-01-02T15:04:05" - LegacyDeviceTimeFormat = "2006-01-02T15:04:05.999Z" + LegacyTimeFormat = "2006-01-02T15:04:05.000Z" NoteLengthMaximum = 1000 NotesLengthMaximum = 100 TagLengthMaximum = 100 @@ -279,7 +279,7 @@ func GetLegacyTimeField(t *time.Time) LegacyIDField { return LegacyIDField{Name: "time", Value: &tVal} } - tVal = (*t).Format(LegacyDeviceTimeFormat) + tVal = (*t).Format(LegacyTimeFormat) return LegacyIDField{Name: "time", Value: &tVal} } @@ -313,7 +313,7 @@ func (b *Base) LegacyIdentityFields() ([]string, error) { if (*b.Time).IsZero() { return nil, errors.New("time is empty") } - return []string{b.Type, *b.DeviceID, (*b.Time).Format(LegacyDeviceTimeFormat)}, nil + return []string{b.Type, *b.DeviceID, (*b.Time).Format(LegacyTimeFormat)}, nil } func (b *Base) GetOrigin() *origin.Origin { diff --git a/data/types/base_test.go b/data/types/base_test.go index b4cb46e4ac..e6c8a8b7cd 100644 --- a/data/types/base_test.go +++ b/data/types/base_test.go @@ -32,6 +32,14 @@ import ( const ExpectedTimeFormat = time.RFC3339Nano var _ = Describe("Base", func() { + Context("constants", func() { + It("legacy time format", func() { + Expect(types.LegacyTimeFormat).To(Equal("2006-01-02T15:04:05.000Z")) + }) + It("device time format", func() { + Expect(types.DeviceTimeFormat).To(Equal("2006-01-02T15:04:05")) + }) + }) Context("New", func() { It("creates a new datum with all values initialized", func() { typ := dataTypesTest.NewType() @@ -978,7 +986,7 @@ var _ = Describe("Base", func() { legacyIDFields, err := datum.LegacyIdentityFields() Expect(err).To(BeNil()) Expect(legacyIDFields).ToNot(BeEmpty()) - Expect(legacyIDFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyDeviceTimeFormat)})) + Expect(legacyIDFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyTimeFormat)})) }) Context("GetLegacyIDFields", func() { From 4541d0d10182a4b4037d65a4526ec14702cf340c Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 5 Aug 2024 19:13:37 +1200 Subject: [PATCH 380/413] fix test formatting --- data/types/activity/physical/physical_test.go | 2 +- data/types/basal/basal_test.go | 2 +- data/types/blood/blood_test.go | 2 +- data/types/blood/glucose/selfmonitored/selfmonitored_test.go | 2 +- data/types/bolus/bolus_test.go | 2 +- data/types/calculator/calculator_test.go | 2 +- data/types/device/device_test.go | 2 +- data/types/food/food_test.go | 2 +- data/types/insulin/insulin_test.go | 2 +- data/types/settings/cgm/cgm_test.go | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/data/types/activity/physical/physical_test.go b/data/types/activity/physical/physical_test.go index f69ad75d9b..5064bc9ca4 100644 --- a/data/types/activity/physical/physical_test.go +++ b/data/types/activity/physical/physical_test.go @@ -1374,7 +1374,7 @@ var _ = Describe("Physical", func() { datum.Time = pointer.FromTime(t) legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{"physicalActivity", "some-device", "2023-05-13T15:51:58Z"})) + Expect(legacyIdentityFields).To(Equal([]string{"physicalActivity", "some-device", "2023-05-13T15:51:58.000Z"})) }) }) }) diff --git a/data/types/basal/basal_test.go b/data/types/basal/basal_test.go index b83559cb0c..a43f36ff74 100644 --- a/data/types/basal/basal_test.go +++ b/data/types/basal/basal_test.go @@ -148,7 +148,7 @@ var _ = Describe("Basal", func() { datum.DeliveryType = "some-delivery" legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{"basal", "some-delivery", "some-device", "2023-05-13T15:51:58Z"})) + Expect(legacyIdentityFields).To(Equal([]string{"basal", "some-delivery", "some-device", "2023-05-13T15:51:58.000Z"})) }) }) }) diff --git a/data/types/blood/blood_test.go b/data/types/blood/blood_test.go index ff36e7b418..93363b22a6 100644 --- a/data/types/blood/blood_test.go +++ b/data/types/blood/blood_test.go @@ -139,7 +139,7 @@ var _ = Describe("Blood", func() { datum.Time = pointer.FromTime(t) legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{"bg", "some-bg-device", "2023-05-13T15:51:58Z"})) + Expect(legacyIdentityFields).To(Equal([]string{"bg", "some-bg-device", "2023-05-13T15:51:58.000Z"})) }) }) diff --git a/data/types/blood/glucose/selfmonitored/selfmonitored_test.go b/data/types/blood/glucose/selfmonitored/selfmonitored_test.go index 7c7610763d..bd33486c3c 100644 --- a/data/types/blood/glucose/selfmonitored/selfmonitored_test.go +++ b/data/types/blood/glucose/selfmonitored/selfmonitored_test.go @@ -571,7 +571,7 @@ var _ = Describe("SelfMonitored", func() { datum.Time = pointer.FromTime(t) legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{"smbg", "some-device", "2023-05-13T15:51:58Z", "12.211645580300173"})) + Expect(legacyIdentityFields).To(Equal([]string{"smbg", "some-device", "2023-05-13T15:51:58.000Z", "12.211645580300173"})) }) }) }) diff --git a/data/types/bolus/bolus_test.go b/data/types/bolus/bolus_test.go index 79642af8c8..70052e11d6 100644 --- a/data/types/bolus/bolus_test.go +++ b/data/types/bolus/bolus_test.go @@ -211,7 +211,7 @@ var _ = Describe("Bolus", func() { datum.SubType = "some-sub-type" legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{"bolus", "some-sub-type", "some-device", "2023-05-13T15:51:58Z"})) + Expect(legacyIdentityFields).To(Equal([]string{"bolus", "some-sub-type", "some-device", "2023-05-13T15:51:58.000Z"})) }) }) }) diff --git a/data/types/calculator/calculator_test.go b/data/types/calculator/calculator_test.go index f7210c861e..111011cb75 100644 --- a/data/types/calculator/calculator_test.go +++ b/data/types/calculator/calculator_test.go @@ -176,7 +176,7 @@ var _ = Describe("Calculator", func() { datum.Time = pointer.FromTime(t) legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{"wizard", "some-device", "2023-05-13T15:51:58Z"})) + Expect(legacyIdentityFields).To(Equal([]string{"wizard", "some-device", "2023-05-13T15:51:58.000Z"})) }) }) diff --git a/data/types/device/device_test.go b/data/types/device/device_test.go index 70ab8bec82..521937dfba 100644 --- a/data/types/device/device_test.go +++ b/data/types/device/device_test.go @@ -149,7 +149,7 @@ var _ = Describe("Device", func() { datum.SubType = "some-sub-type" legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{"deviceEvent", "some-sub-type", "2023-05-13T15:51:58Z", "some-device"})) + Expect(legacyIdentityFields).To(Equal([]string{"deviceEvent", "some-sub-type", "2023-05-13T15:51:58.000Z", "some-device"})) }) }) }) diff --git a/data/types/food/food_test.go b/data/types/food/food_test.go index 728e34fb93..2a634527a2 100644 --- a/data/types/food/food_test.go +++ b/data/types/food/food_test.go @@ -444,7 +444,7 @@ var _ = Describe("Food", func() { datum.Time = pointer.FromTime(t) legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{"food", "some-device", "2023-05-13T15:51:58Z"})) + Expect(legacyIdentityFields).To(Equal([]string{"food", "some-device", "2023-05-13T15:51:58.000Z"})) }) }) }) diff --git a/data/types/insulin/insulin_test.go b/data/types/insulin/insulin_test.go index 92ab70ad70..aa07e1da25 100644 --- a/data/types/insulin/insulin_test.go +++ b/data/types/insulin/insulin_test.go @@ -178,7 +178,7 @@ var _ = Describe("Insulin", func() { datum.Time = pointer.FromTime(t) legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{"insulin", "some-pump-device", "2023-05-13T15:51:58Z"})) + Expect(legacyIdentityFields).To(Equal([]string{"insulin", "some-pump-device", "2023-05-13T15:51:58.000Z"})) }) }) }) diff --git a/data/types/settings/cgm/cgm_test.go b/data/types/settings/cgm/cgm_test.go index 40ed5f685d..dc1830a8c4 100644 --- a/data/types/settings/cgm/cgm_test.go +++ b/data/types/settings/cgm/cgm_test.go @@ -606,7 +606,7 @@ var _ = Describe("CGM", func() { datum.Time = pointer.FromTime(t) legacyIdentityFields, err := datum.LegacyIdentityFields() Expect(err).ToNot(HaveOccurred()) - Expect(legacyIdentityFields).To(Equal([]string{"cgmSettings", "2023-05-13T15:51:58Z", "some-cgm-device"})) + Expect(legacyIdentityFields).To(Equal([]string{"cgmSettings", "2023-05-13T15:51:58.000Z", "some-cgm-device"})) }) }) }) From 5279675fe9fdeaebb00f008a520e00663ed60b12 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 6 Aug 2024 12:37:59 +1200 Subject: [PATCH 381/413] version naming and debug --- .../deduplicator/device_deactivate_hash.go | 28 ++++---- data/deduplicator/deduplicator/hash.go | 19 +++-- data/deduplicator/deduplicator/hash_test.go | 72 ++++++++++--------- 3 files changed, 68 insertions(+), 51 deletions(-) diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index fc5ab386b3..f651db081f 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -12,9 +12,9 @@ import ( type DeviceDeactivateHashVersion string const ( - UnkownVersion DeviceDeactivateHashVersion = "" - CurrentVersion DeviceDeactivateHashVersion = "1.1.0" - LegacyVersion DeviceDeactivateHashVersion = "0.0.0" + DeviceDeactivateHashVersionUnkown DeviceDeactivateHashVersion = "" + DeviceDeactivateHashVersionCurrent DeviceDeactivateHashVersion = "1.1.0" + DeviceDeactivateHashVersionLegacy DeviceDeactivateHashVersion = "0.0.0" ) const DeviceDeactivateHashName = "org.tidepool.deduplicator.device.deactivate.hash" @@ -43,7 +43,7 @@ type DeviceDeactivateHash struct { } func NewDeviceDeactivateLegacyHash() (*DeviceDeactivateHash, error) { - base, err := NewBase(DeviceDeactivateHashName, string(LegacyVersion)) + base, err := NewBase(DeviceDeactivateHashName, string(DeviceDeactivateHashVersionLegacy)) if err != nil { return nil, err } @@ -54,7 +54,7 @@ func NewDeviceDeactivateLegacyHash() (*DeviceDeactivateHash, error) { } func NewDeviceDeactivateHash() (*DeviceDeactivateHash, error) { - base, err := NewBase(DeviceDeactivateHashName, string(CurrentVersion)) + base, err := NewBase(DeviceDeactivateHashName, string(DeviceDeactivateHashVersionCurrent)) if err != nil { return nil, err } @@ -68,10 +68,10 @@ func getDeviceDeactivateHashVersion(dataSet *dataTypesUpload.Upload) DeviceDeact if dataSet.Deduplicator != nil { if dataSet.Deduplicator.Name != nil && dataSet.Deduplicator.Version != nil { if *dataSet.Deduplicator.Name == DeviceDeactivateHashName { - if *dataSet.Deduplicator.Version == string(LegacyVersion) { - return LegacyVersion - } else if *dataSet.Deduplicator.Version == string(CurrentVersion) { - return CurrentVersion + if *dataSet.Deduplicator.Version == string(DeviceDeactivateHashVersionLegacy) { + return DeviceDeactivateHashVersionLegacy + } else if *dataSet.Deduplicator.Version == string(DeviceDeactivateHashVersionCurrent) { + return DeviceDeactivateHashVersionCurrent } } } @@ -81,7 +81,7 @@ func getDeviceDeactivateHashVersion(dataSet *dataTypesUpload.Upload) DeviceDeact if allowedDeviceModels, found := DeviceDeactivateLegacyHashManufacturerDeviceModels[deviceManufacturer]; found { for _, allowedDeviceModel := range allowedDeviceModels { if allowedDeviceModel == *dataSet.DeviceModel { - return LegacyVersion + return DeviceDeactivateHashVersionLegacy } } } @@ -90,13 +90,13 @@ func getDeviceDeactivateHashVersion(dataSet *dataTypesUpload.Upload) DeviceDeact if allowedDeviceModels, found := DeviceDeactivateHashDeviceManufacturerDeviceModels[deviceManufacturer]; found { for _, allowedDeviceModel := range allowedDeviceModels { if allowedDeviceModel == *dataSet.DeviceModel { - return CurrentVersion + return DeviceDeactivateHashVersionCurrent } } } } } - return UnkownVersion + return DeviceDeactivateHashVersionUnkown } func (d *DeviceDeactivateHash) New(dataSet *dataTypesUpload.Upload) (bool, error) { @@ -112,7 +112,7 @@ func (d *DeviceDeactivateHash) New(dataSet *dataTypesUpload.Upload) (bool, error if dataSet.HasDeduplicatorName() { return d.Get(dataSet) } - return getDeviceDeactivateHashVersion(dataSet) != UnkownVersion, nil + return getDeviceDeactivateHashVersion(dataSet) != DeviceDeactivateHashVersionUnkown, nil } func (d *DeviceDeactivateHash) Get(dataSet *dataTypesUpload.Upload) (bool, error) { @@ -121,7 +121,7 @@ func (d *DeviceDeactivateHash) Get(dataSet *dataTypesUpload.Upload) (bool, error return false, errors.New("data set is missing") } - if getDeviceDeactivateHashVersion(dataSet) == LegacyVersion { + if getDeviceDeactivateHashVersion(dataSet) == DeviceDeactivateHashVersionLegacy { return true, nil } diff --git a/data/deduplicator/deduplicator/hash.go b/data/deduplicator/deduplicator/hash.go index 3ab79a2789..dbfa1be770 100644 --- a/data/deduplicator/deduplicator/hash.go +++ b/data/deduplicator/deduplicator/hash.go @@ -17,15 +17,17 @@ import ( func AssignDataSetDataIdentityHashes(dataSetData data.Data, version DeviceDeactivateHashVersion) error { for _, dataSetDatum := range dataSetData { var hash string - if version == LegacyVersion { + if version == DeviceDeactivateHashVersionLegacy { fields, err := dataSetDatum.LegacyIdentityFields() if err != nil { return errors.Wrapf(err, "unable to gather legacy identity fields for datum %T", dataSetDatum) } if dataSetDatum.GetType() == "smbg" { log.Printf("SMBG LegacyIdentityFields are [%v]", fields) + hash, err = GenerateLegacyIdentityHash(fields, true) + } else { + hash, err = GenerateLegacyIdentityHash(fields, false) } - hash, err = GenerateLegacyIdentityHash(fields) if err != nil { return errors.Wrapf(err, "unable to generate legacy identity hash for datum %T", dataSetDatum) @@ -69,18 +71,27 @@ func GenerateIdentityHash(identityFields []string) (string, error) { return identityHash, nil } -func GenerateLegacyIdentityHash(identityFields []string) (string, error) { +func GenerateLegacyIdentityHash(identityFields []string, debugHash bool) (string, error) { + if len(identityFields) == 0 { return "", errors.New("identity fields are missing") } hasher := sha1.New() + hashStr := "" for _, identityField := range identityFields { if identityField == "" { return "", errors.New("identity field is empty") } - hasher.Write([]byte(fmt.Sprintf("%v_", identityField))) + hashStr += fmt.Sprintf("%v_", strings.TrimSpace(identityField)) + hasher.Write([]byte(fmt.Sprintf("%v_", strings.TrimSpace(identityField)))) } + hashStr += "bootstrap_" hasher.Write([]byte("bootstrap_")) hash := hasher.Sum(nil) + + if debugHash { + log.Printf("Platform SMBG hash string %s", string(hashStr)) + } + return base32.NewEncoding("0123456789abcdefghijklmnopqrstuv").WithPadding('-').EncodeToString(hash), nil } diff --git a/data/deduplicator/deduplicator/hash_test.go b/data/deduplicator/deduplicator/hash_test.go index cfefc272a5..6a37959a14 100644 --- a/data/deduplicator/deduplicator/hash_test.go +++ b/data/deduplicator/deduplicator/hash_test.go @@ -40,25 +40,25 @@ var _ = Describe("Hash", func() { }) It("returns successfully when the data is nil", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(nil, dataDeduplicatorDeduplicator.CurrentVersion)).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(nil, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent)).To(Succeed()) }) It("returns successfully when there is no data", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(nil, dataDeduplicatorDeduplicator.LegacyVersion)).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(nil, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy)).To(Succeed()) }) It("returns successfully when there is no data", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(data.Data{}, dataDeduplicatorDeduplicator.CurrentVersion)).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(data.Data{}, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent)).To(Succeed()) }) It("returns successfully when there is no data", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(data.Data{}, dataDeduplicatorDeduplicator.LegacyVersion)).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(data.Data{}, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy)).To(Succeed()) }) It("returns an error when any datum returns an error getting identity fields", func() { dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: nil, Error: errors.New("test error")}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.CurrentVersion)).To(MatchError("unable to gather identity fields for datum; test error")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent)).To(MatchError("unable to gather identity fields for datum; test error")) }) It("returns an error when any datum returns an error getting legacy identity fields", func() { @@ -66,13 +66,13 @@ var _ = Describe("Hash", func() { dataSetDataTest[0].GetTypeOutputs = []string{"test-type"} dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: nil, Error: errors.New("test error")}} dataSetDataTest[1].GetTypeOutputs = []string{"test-type"} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.LegacyVersion)).To(MatchError("unable to gather legacy identity fields for datum *test.Datum; test error")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy)).To(MatchError("unable to gather legacy identity fields for datum *test.Datum; test error")) }) It("returns an error when any datum returns no identity fields", func() { dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: nil, Error: nil}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.CurrentVersion)).To(MatchError("unable to generate identity hash for datum; identity fields are missing")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent)).To(MatchError("unable to generate identity hash for datum; identity fields are missing")) }) It("returns an error when any datum returns no legacy identity fields", func() { @@ -80,13 +80,13 @@ var _ = Describe("Hash", func() { dataSetDataTest[0].GetTypeOutputs = []string{"test-type"} dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: nil, Error: nil}} dataSetDataTest[1].GetTypeOutputs = []string{"test-type"} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.LegacyVersion)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity fields are missing")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity fields are missing")) }) It("returns an error when any datum returns empty identity fields", func() { dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{}, Error: nil}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.CurrentVersion)).To(MatchError("unable to generate identity hash for datum; identity fields are missing")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent)).To(MatchError("unable to generate identity hash for datum; identity fields are missing")) }) It("returns an error when any datum returns empty legacy identity fields", func() { @@ -94,13 +94,13 @@ var _ = Describe("Hash", func() { dataSetDataTest[0].GetTypeOutputs = []string{"test-type"} dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{}, Error: nil}} dataSetDataTest[1].GetTypeOutputs = []string{"test-type"} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.LegacyVersion)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity fields are missing")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity fields are missing")) }) It("returns an error when any datum returns any empty identity fields", func() { dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), ""}, Error: nil}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.CurrentVersion)).To(MatchError("unable to generate identity hash for datum; identity field is empty")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent)).To(MatchError("unable to generate identity hash for datum; identity field is empty")) }) It("returns an error when any datum returns any empty legacy identity fields", func() { @@ -108,7 +108,7 @@ var _ = Describe("Hash", func() { dataSetDataTest[0].GetTypeOutputs = []string{"test-type"} dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), ""}, Error: nil}} dataSetDataTest[1].GetTypeOutputs = []string{"test-type"} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.LegacyVersion)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity field is empty")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity field is empty")) }) Context("with identity fields", func() { @@ -125,7 +125,7 @@ var _ = Describe("Hash", func() { }) It("returns successfully", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.CurrentVersion)).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent)).To(Succeed()) }) }) @@ -146,7 +146,7 @@ var _ = Describe("Hash", func() { }) It("returns successfully", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.LegacyVersion)).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy)).To(Succeed()) }) }) @@ -173,7 +173,7 @@ var _ = Describe("Hash", func() { }) It("returns successfully", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(smbgData, dataDeduplicatorDeduplicator.LegacyVersion)).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(smbgData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy)).To(Succeed()) }) }) @@ -212,26 +212,26 @@ var _ = Describe("Hash", func() { }) Context("GenerateLegacyIdentityHash", func() { It("returns an error when identity fields is missing", func() { - hash, err := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash(nil) + hash, err := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash(nil, false) Expect(err).To(MatchError("identity fields are missing")) Expect(hash).To(BeEmpty()) }) It("returns an error when identity fields is empty", func() { - hash, err := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash([]string{}) + hash, err := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash([]string{}, false) Expect(err).To(MatchError("identity fields are missing")) Expect(hash).To(BeEmpty()) }) It("returns an error when an identity fields empty", func() { - hash, err := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash([]string{"alpha", "", "charlie"}) + hash, err := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash([]string{"alpha", "", "charlie"}, false) Expect(err).To(MatchError("identity field is empty")) Expect(hash).To(BeEmpty()) }) DescribeTable("hash from legacy identity tests", func(fields []string, expectedHash string, expectedErr error) { - actualHash, actualErr := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash(fields) + actualHash, actualErr := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash(fields, true) if expectedErr != nil { Expect(actualErr).To(Equal(expectedErr)) } else { @@ -239,20 +239,26 @@ var _ = Describe("Hash", func() { Expect(actualErr).To(BeNil()) } }, - Entry("smbg id", []string{"smbg", "tools", "2014-06-11T11:12:43.029Z", "5.550747991045533"}, "e2ihon9nqcro96c4uugb4ftdnr07nqok", nil), - Entry("smbg id", []string{"smbg", "tools", "2014-06-11T17:57:01.703Z", "4.5"}, "c14eds071pp5gsirfmgmsclbcahs8th0", nil), - Entry("smbg id", []string{"smbg", "tools", "2015-07-04T10:13:00.000Z", "4.9"}, "rk2htms97m7hipdu5lrso7ufd3pedm6n", nil), - Entry("smbg id", []string{"smbg", "tools", "2015-07-04T10:13:00.000Z", "4.8"}, "urrkdln86rl4vhqckps6gnupg5njqk6n", nil), - - Entry("cbg id", []string{"cbg", "tools", "2014-06-11T11:12:43.029Z"}, "eb12p6h892pmd0hhccpt2r17muc407o0", nil), - Entry("cbg id", []string{"cbg", "tools", "2014-06-11T17:57:01.703Z"}, "ha2ogn1kenqqhseed504sqnanhnclg5s", nil), - Entry("cbg id", []string{"cbg", "tools", "2014-06-12T11:12:43.029Z"}, "i922lobl3kron3t81pjap31anopkspvb", nil), - Entry("cbg id", []string{"cbg", "DexHealthKit_Dexcom:com.dexcom.Share2:3.0.4.17", "2015-12-21T11:23:08Z"}, "nsikjhfaprplpq78hc7di2lu5qpt1e3k", nil), - - Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T00:00:00.000Z"}, "kmm427pfbrc6rugtmbuli8j4q61u17uk", nil), - Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T06:00:00.000Z"}, "cjou7vscvp8ogv34d6vejootulqfn3jd", nil), - Entry("basal id", []string{"basal", "temp", "tools", "2014-06-11T09:00:00.000Z"}, "tn33bjb0241j9qh4jg9vdnf1g6k1g9r8", nil), - Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T19:00:00.000Z"}, "kftn188l8rjuvma3qkd3iqg34t0plajp", nil), + // Entry("smbg id", []string{"smbg", "tools", "2014-06-11T11:12:43.029Z", "5.550747991045533"}, "e2ihon9nqcro96c4uugb4ftdnr07nqok", nil), + // Entry("smbg id", []string{"smbg", "tools", "2014-06-11T17:57:01.703Z", "4.5"}, "c14eds071pp5gsirfmgmsclbcahs8th0", nil), + // Entry("smbg id", []string{"smbg", "tools", "2015-07-04T10:13:00.000Z", "4.9"}, "rk2htms97m7hipdu5lrso7ufd3pedm6n", nil), + // Entry("smbg id", []string{"smbg", "tools", "2015-07-04T10:13:00.000Z", "4.8"}, "urrkdln86rl4vhqckps6gnupg5njqk6n", nil), + + Entry("smbg id", []string{"smbg", "tandemCIQ1002717664049", "2023-05-13T15:51:58.000Z", "12.211645580300173"}, "o5d5o0q9g1s70prg609osop8s4sg182f", nil), + Entry("smbg id", []string{"smbg", "tandemCIQ1002717664049", "2023-05-12T15:21:16.000Z", "7.382494828090559"}, "pr2b3dii5hddtlo3i973t8rat2blm3n0", nil), + Entry("smbg id", []string{"smbg", "tandemCIQ1002717664049", "2023-03-27T15:38:59.000Z", "7.49350978791147"}, "dotp56ahq7m8ehesfep0rimmo6rooaht", nil), + Entry("smbg id", []string{"smbg", "tandemCIQ1002717664049", "2023-02-06T07:38:17.000Z", "15.153542015554306"}, "bo06rjosvq671bi55fj6gbu95nu2lrrt", nil), + Entry("smbg id", []string{"smbg", "tandemCIQ1002717664049", "2023-02-06T07:16:27.000Z", "13.821362497703378"}, "nj1elbn2ql6qpeecbn1r5c7qoqvvc1oj", nil), + + // Entry("cbg id", []string{"cbg", "tools", "2014-06-11T11:12:43.029Z"}, "eb12p6h892pmd0hhccpt2r17muc407o0", nil), + // Entry("cbg id", []string{"cbg", "tools", "2014-06-11T17:57:01.703Z"}, "ha2ogn1kenqqhseed504sqnanhnclg5s", nil), + // Entry("cbg id", []string{"cbg", "tools", "2014-06-12T11:12:43.029Z"}, "i922lobl3kron3t81pjap31anopkspvb", nil), + // Entry("cbg id", []string{"cbg", "DexHealthKit_Dexcom:com.dexcom.Share2:3.0.4.17", "2015-12-21T11:23:08Z"}, "nsikjhfaprplpq78hc7di2lu5qpt1e3k", nil), + + // Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T00:00:00.000Z"}, "kmm427pfbrc6rugtmbuli8j4q61u17uk", nil), + // Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T06:00:00.000Z"}, "cjou7vscvp8ogv34d6vejootulqfn3jd", nil), + // Entry("basal id", []string{"basal", "temp", "tools", "2014-06-11T09:00:00.000Z"}, "tn33bjb0241j9qh4jg9vdnf1g6k1g9r8", nil), + // Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T19:00:00.000Z"}, "kftn188l8rjuvma3qkd3iqg34t0plajp", nil), ) }) }) From d51f3ca212e94869845141073aeb64d3b8662ff4 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 7 Aug 2024 13:49:11 +1200 Subject: [PATCH 382/413] start using _groupId for legacy hash --- data/data_set.go | 2 + .../deduplicator/device_deactivate_hash.go | 18 ++++- data/deduplicator/deduplicator/hash.go | 70 ++++++++++------ data/deduplicator/deduplicator/hash_test.go | 80 +++++++++---------- 4 files changed, 103 insertions(+), 67 deletions(-) diff --git a/data/data_set.go b/data/data_set.go index ee3456e98a..fe2df24efb 100644 --- a/data/data_set.go +++ b/data/data_set.go @@ -111,6 +111,7 @@ func (d *DataSetClient) Validate(validator structure.Validator) { type DataSetFilter struct { ClientName *string + IsLegacy *bool Deleted *bool DeviceID *string } @@ -321,6 +322,7 @@ type DataSet struct { Type string `json:"type,omitempty" bson:"type,omitempty"` UploadID *string `json:"uploadId,omitempty" bson:"uploadId,omitempty"` UserID *string `json:"-" bson:"_userId,omitempty"` + LegacyGroupID *string `json:"-" bson:"_groupId,omitempty"` Version *string `json:"version,omitempty" bson:"version,omitempty"` VersionInternal int `json:"-" bson:"_version,omitempty"` } diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index f651db081f..f687b1ad06 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -145,7 +145,23 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore return errors.New("data set data is missing") } - if err := AssignDataSetDataIdentityHashes(dataSetData, getDeviceDeactivateHashVersion(dataSet)); err != nil { + opts := NewDefaultDeviceDeactivateHashOptions() + + if getDeviceDeactivateHashVersion(dataSet) == DeviceDeactivateHashVersionLegacy { + // TODO: find the last upload if there was one + // + // uploads, err := repository.GetDataSetsForUserByID(ctx, *dataSet.UserID, &dataStore.Filter{}, &page.Pagination{Page: 1, Size: 1}) + // if dataSetData == nil { + // return err + // } + // if len(uploads) != 0 { + // deviceDeactivateHashVersion = DeviceDeactivateHashVersionLegacy + // } + // NOTE: hard coded to test + opts = NewLegacyDeviceDeactivateHashOptions("7394e6ad03") + } + + if err := AssignDataSetDataIdentityHashes(dataSetData, opts); err != nil { return err } return d.Base.AddData(ctx, repository, dataSet, dataSetData) diff --git a/data/deduplicator/deduplicator/hash.go b/data/deduplicator/deduplicator/hash.go index dbfa1be770..7c8103c98e 100644 --- a/data/deduplicator/deduplicator/hash.go +++ b/data/deduplicator/deduplicator/hash.go @@ -6,7 +6,6 @@ import ( "encoding/base32" "encoding/base64" "fmt" - "log" "strings" "github.com/tidepool-org/platform/data" @@ -14,24 +13,53 @@ import ( "github.com/tidepool-org/platform/pointer" ) -func AssignDataSetDataIdentityHashes(dataSetData data.Data, version DeviceDeactivateHashVersion) error { +type deviceDeactivateHashOptions struct { + version DeviceDeactivateHashVersion + legacyGroupID *string +} + +func NewLegacyDeviceDeactivateHashOptions(legacyGroupID string) deviceDeactivateHashOptions { + return deviceDeactivateHashOptions{ + version: DeviceDeactivateHashVersionLegacy, + legacyGroupID: &legacyGroupID, + } +} + +func NewDefaultDeviceDeactivateHashOptions() deviceDeactivateHashOptions { + return deviceDeactivateHashOptions{ + version: DeviceDeactivateHashVersionCurrent, + } +} + +func (d deviceDeactivateHashOptions) ValidateLegacy() error { + if d.version == DeviceDeactivateHashVersionLegacy { + if d.legacyGroupID == nil || *d.legacyGroupID == "" { + return errors.New("missing required legacy groupId for the device deactive hash legacy version") + } + } + return nil +} + +func AssignDataSetDataIdentityHashes(dataSetData data.Data, opts deviceDeactivateHashOptions) error { for _, dataSetDatum := range dataSetData { var hash string - if version == DeviceDeactivateHashVersionLegacy { + if opts.version == DeviceDeactivateHashVersionLegacy { + if err := opts.ValidateLegacy(); err != nil { + return err + } fields, err := dataSetDatum.LegacyIdentityFields() if err != nil { return errors.Wrapf(err, "unable to gather legacy identity fields for datum %T", dataSetDatum) } - if dataSetDatum.GetType() == "smbg" { - log.Printf("SMBG LegacyIdentityFields are [%v]", fields) - hash, err = GenerateLegacyIdentityHash(fields, true) - } else { - hash, err = GenerateLegacyIdentityHash(fields, false) - } + hash, err = GenerateLegacyIdentityHash(fields) if err != nil { return errors.Wrapf(err, "unable to generate legacy identity hash for datum %T", dataSetDatum) } + hash, err = GenerateLegacyIdentityHash([]string{hash, *opts.legacyGroupID}) + if err != nil { + return errors.Wrapf(err, "unable to generate legacy identity hash with legacy groupID for datum %T", dataSetDatum) + } } else { fields, err := dataSetDatum.IdentityFields() if err != nil { @@ -71,27 +99,21 @@ func GenerateIdentityHash(identityFields []string) (string, error) { return identityHash, nil } -func GenerateLegacyIdentityHash(identityFields []string, debugHash bool) (string, error) { - +func GenerateLegacyIdentityHash(identityFields []string) (string, error) { if len(identityFields) == 0 { return "", errors.New("identity fields are missing") } hasher := sha1.New() - hashStr := "" - for _, identityField := range identityFields { - if identityField == "" { + for _, val := range identityFields { + if val == "" { return "", errors.New("identity field is empty") } - hashStr += fmt.Sprintf("%v_", strings.TrimSpace(identityField)) - hasher.Write([]byte(fmt.Sprintf("%v_", strings.TrimSpace(identityField)))) - } - hashStr += "bootstrap_" - hasher.Write([]byte("bootstrap_")) - hash := hasher.Sum(nil) - - if debugHash { - log.Printf("Platform SMBG hash string %s", string(hashStr)) + hasher.Write([]byte(fmt.Sprintf("%v", val))) + hasher.Write([]byte("_")) } - return base32.NewEncoding("0123456789abcdefghijklmnopqrstuv").WithPadding('-').EncodeToString(hash), nil + hasher.Write([]byte("bootstrap")) + hasher.Write([]byte("_")) + digest := hasher.Sum(nil) + return base32.NewEncoding("0123456789abcdefghijklmnopqrstuv").WithPadding('-').EncodeToString(digest), nil } diff --git a/data/deduplicator/deduplicator/hash_test.go b/data/deduplicator/deduplicator/hash_test.go index 6a37959a14..700b3ce6c7 100644 --- a/data/deduplicator/deduplicator/hash_test.go +++ b/data/deduplicator/deduplicator/hash_test.go @@ -22,6 +22,8 @@ var _ = Describe("Hash", func() { Context("AssignDataSetDataIdentityHashes", func() { var dataSetDataTest []*dataTest.Datum var dataSetData data.Data + legacyOpts := dataDeduplicatorDeduplicator.NewLegacyDeviceDeactivateHashOptions("legacy-group-id") + defaultOpts := dataDeduplicatorDeduplicator.NewDefaultDeviceDeactivateHashOptions() BeforeEach(func() { dataSetDataTest = []*dataTest.Datum{} @@ -40,25 +42,25 @@ var _ = Describe("Hash", func() { }) It("returns successfully when the data is nil", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(nil, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent)).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(nil, defaultOpts)).To(Succeed()) }) It("returns successfully when there is no data", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(nil, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy)).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(nil, legacyOpts)).To(Succeed()) }) It("returns successfully when there is no data", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(data.Data{}, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent)).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(data.Data{}, defaultOpts)).To(Succeed()) }) It("returns successfully when there is no data", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(data.Data{}, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy)).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(data.Data{}, legacyOpts)).To(Succeed()) }) It("returns an error when any datum returns an error getting identity fields", func() { dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: nil, Error: errors.New("test error")}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent)).To(MatchError("unable to gather identity fields for datum; test error")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, defaultOpts)).To(MatchError("unable to gather identity fields for datum; test error")) }) It("returns an error when any datum returns an error getting legacy identity fields", func() { @@ -66,13 +68,13 @@ var _ = Describe("Hash", func() { dataSetDataTest[0].GetTypeOutputs = []string{"test-type"} dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: nil, Error: errors.New("test error")}} dataSetDataTest[1].GetTypeOutputs = []string{"test-type"} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy)).To(MatchError("unable to gather legacy identity fields for datum *test.Datum; test error")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, legacyOpts)).To(MatchError("unable to gather legacy identity fields for datum *test.Datum; test error")) }) It("returns an error when any datum returns no identity fields", func() { dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: nil, Error: nil}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent)).To(MatchError("unable to generate identity hash for datum; identity fields are missing")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, defaultOpts)).To(MatchError("unable to generate identity hash for datum; identity fields are missing")) }) It("returns an error when any datum returns no legacy identity fields", func() { @@ -80,13 +82,13 @@ var _ = Describe("Hash", func() { dataSetDataTest[0].GetTypeOutputs = []string{"test-type"} dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: nil, Error: nil}} dataSetDataTest[1].GetTypeOutputs = []string{"test-type"} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity fields are missing")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, legacyOpts)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity fields are missing")) }) It("returns an error when any datum returns empty identity fields", func() { dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{}, Error: nil}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent)).To(MatchError("unable to generate identity hash for datum; identity fields are missing")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, defaultOpts)).To(MatchError("unable to generate identity hash for datum; identity fields are missing")) }) It("returns an error when any datum returns empty legacy identity fields", func() { @@ -94,13 +96,13 @@ var _ = Describe("Hash", func() { dataSetDataTest[0].GetTypeOutputs = []string{"test-type"} dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{}, Error: nil}} dataSetDataTest[1].GetTypeOutputs = []string{"test-type"} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity fields are missing")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, legacyOpts)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity fields are missing")) }) It("returns an error when any datum returns any empty identity fields", func() { dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), ""}, Error: nil}} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent)).To(MatchError("unable to generate identity hash for datum; identity field is empty")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, defaultOpts)).To(MatchError("unable to generate identity hash for datum; identity field is empty")) }) It("returns an error when any datum returns any empty legacy identity fields", func() { @@ -108,7 +110,7 @@ var _ = Describe("Hash", func() { dataSetDataTest[0].GetTypeOutputs = []string{"test-type"} dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), ""}, Error: nil}} dataSetDataTest[1].GetTypeOutputs = []string{"test-type"} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity field is empty")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, legacyOpts)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity field is empty")) }) Context("with identity fields", func() { @@ -125,7 +127,7 @@ var _ = Describe("Hash", func() { }) It("returns successfully", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent)).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, defaultOpts)).To(Succeed()) }) }) @@ -140,13 +142,13 @@ var _ = Describe("Hash", func() { }) AfterEach(func() { - Expect(dataSetDataTest[0].DeduplicatorDescriptorValue).To(Equal(&data.DeduplicatorDescriptor{Hash: pointer.FromString("1i2gupee95mf7ooatr0cveo9qr6dt2i6")})) - Expect(dataSetDataTest[1].DeduplicatorDescriptorValue).To(Equal(&data.DeduplicatorDescriptor{Hash: pointer.FromString("f0mq6bk3d79aua8lre8ti8bosqkaf10d")})) - Expect(dataSetDataTest[2].DeduplicatorDescriptorValue).To(Equal(&data.DeduplicatorDescriptor{Hash: pointer.FromString("sknnju4it96cqsbcmuh3g1navg1kdvp5")})) + Expect(dataSetDataTest[0].DeduplicatorDescriptorValue).To(Equal(&data.DeduplicatorDescriptor{Hash: pointer.FromString("qspej2rl2vhbui2om3822pb0hh5dvthj")})) + Expect(dataSetDataTest[1].DeduplicatorDescriptorValue).To(Equal(&data.DeduplicatorDescriptor{Hash: pointer.FromString("r75b33k9gqtdo938gnoisu8cgq0rupaf")})) + Expect(dataSetDataTest[2].DeduplicatorDescriptorValue).To(Equal(&data.DeduplicatorDescriptor{Hash: pointer.FromString("r4dlls57b4ro07kufocso8ts46h4h70q")})) }) It("returns successfully", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy)).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, legacyOpts)).To(Succeed()) }) }) @@ -173,7 +175,7 @@ var _ = Describe("Hash", func() { }) It("returns successfully", func() { - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(smbgData, dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy)).To(Succeed()) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(smbgData, legacyOpts)).To(Succeed()) }) }) @@ -212,26 +214,26 @@ var _ = Describe("Hash", func() { }) Context("GenerateLegacyIdentityHash", func() { It("returns an error when identity fields is missing", func() { - hash, err := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash(nil, false) + hash, err := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash(nil) Expect(err).To(MatchError("identity fields are missing")) Expect(hash).To(BeEmpty()) }) It("returns an error when identity fields is empty", func() { - hash, err := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash([]string{}, false) + hash, err := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash([]string{}) Expect(err).To(MatchError("identity fields are missing")) Expect(hash).To(BeEmpty()) }) It("returns an error when an identity fields empty", func() { - hash, err := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash([]string{"alpha", "", "charlie"}, false) + hash, err := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash([]string{"alpha", "", "charlie"}) Expect(err).To(MatchError("identity field is empty")) Expect(hash).To(BeEmpty()) }) DescribeTable("hash from legacy identity tests", func(fields []string, expectedHash string, expectedErr error) { - actualHash, actualErr := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash(fields, true) + actualHash, actualErr := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash(fields) if expectedErr != nil { Expect(actualErr).To(Equal(expectedErr)) } else { @@ -239,26 +241,20 @@ var _ = Describe("Hash", func() { Expect(actualErr).To(BeNil()) } }, - // Entry("smbg id", []string{"smbg", "tools", "2014-06-11T11:12:43.029Z", "5.550747991045533"}, "e2ihon9nqcro96c4uugb4ftdnr07nqok", nil), - // Entry("smbg id", []string{"smbg", "tools", "2014-06-11T17:57:01.703Z", "4.5"}, "c14eds071pp5gsirfmgmsclbcahs8th0", nil), - // Entry("smbg id", []string{"smbg", "tools", "2015-07-04T10:13:00.000Z", "4.9"}, "rk2htms97m7hipdu5lrso7ufd3pedm6n", nil), - // Entry("smbg id", []string{"smbg", "tools", "2015-07-04T10:13:00.000Z", "4.8"}, "urrkdln86rl4vhqckps6gnupg5njqk6n", nil), - - Entry("smbg id", []string{"smbg", "tandemCIQ1002717664049", "2023-05-13T15:51:58.000Z", "12.211645580300173"}, "o5d5o0q9g1s70prg609osop8s4sg182f", nil), - Entry("smbg id", []string{"smbg", "tandemCIQ1002717664049", "2023-05-12T15:21:16.000Z", "7.382494828090559"}, "pr2b3dii5hddtlo3i973t8rat2blm3n0", nil), - Entry("smbg id", []string{"smbg", "tandemCIQ1002717664049", "2023-03-27T15:38:59.000Z", "7.49350978791147"}, "dotp56ahq7m8ehesfep0rimmo6rooaht", nil), - Entry("smbg id", []string{"smbg", "tandemCIQ1002717664049", "2023-02-06T07:38:17.000Z", "15.153542015554306"}, "bo06rjosvq671bi55fj6gbu95nu2lrrt", nil), - Entry("smbg id", []string{"smbg", "tandemCIQ1002717664049", "2023-02-06T07:16:27.000Z", "13.821362497703378"}, "nj1elbn2ql6qpeecbn1r5c7qoqvvc1oj", nil), - - // Entry("cbg id", []string{"cbg", "tools", "2014-06-11T11:12:43.029Z"}, "eb12p6h892pmd0hhccpt2r17muc407o0", nil), - // Entry("cbg id", []string{"cbg", "tools", "2014-06-11T17:57:01.703Z"}, "ha2ogn1kenqqhseed504sqnanhnclg5s", nil), - // Entry("cbg id", []string{"cbg", "tools", "2014-06-12T11:12:43.029Z"}, "i922lobl3kron3t81pjap31anopkspvb", nil), - // Entry("cbg id", []string{"cbg", "DexHealthKit_Dexcom:com.dexcom.Share2:3.0.4.17", "2015-12-21T11:23:08Z"}, "nsikjhfaprplpq78hc7di2lu5qpt1e3k", nil), - - // Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T00:00:00.000Z"}, "kmm427pfbrc6rugtmbuli8j4q61u17uk", nil), - // Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T06:00:00.000Z"}, "cjou7vscvp8ogv34d6vejootulqfn3jd", nil), - // Entry("basal id", []string{"basal", "temp", "tools", "2014-06-11T09:00:00.000Z"}, "tn33bjb0241j9qh4jg9vdnf1g6k1g9r8", nil), - // Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T19:00:00.000Z"}, "kftn188l8rjuvma3qkd3iqg34t0plajp", nil), + Entry("smbg id", []string{"smbg", "tools", "2014-06-11T11:12:43.029Z", "5.550747991045533"}, "e2ihon9nqcro96c4uugb4ftdnr07nqok", nil), + Entry("smbg id", []string{"smbg", "tools", "2014-06-11T17:57:01.703Z", "4.5"}, "c14eds071pp5gsirfmgmsclbcahs8th0", nil), + Entry("smbg id", []string{"smbg", "tools", "2015-07-04T10:13:00.000Z", "4.9"}, "rk2htms97m7hipdu5lrso7ufd3pedm6n", nil), + Entry("smbg id", []string{"smbg", "tools", "2015-07-04T10:13:00.000Z", "4.8"}, "urrkdln86rl4vhqckps6gnupg5njqk6n", nil), + + Entry("cbg id", []string{"cbg", "tools", "2014-06-11T11:12:43.029Z"}, "eb12p6h892pmd0hhccpt2r17muc407o0", nil), + Entry("cbg id", []string{"cbg", "tools", "2014-06-11T17:57:01.703Z"}, "ha2ogn1kenqqhseed504sqnanhnclg5s", nil), + Entry("cbg id", []string{"cbg", "tools", "2014-06-12T11:12:43.029Z"}, "i922lobl3kron3t81pjap31anopkspvb", nil), + Entry("cbg id", []string{"cbg", "DexHealthKit_Dexcom:com.dexcom.Share2:3.0.4.17", "2015-12-21T11:23:08Z"}, "nsikjhfaprplpq78hc7di2lu5qpt1e3k", nil), + + Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T00:00:00.000Z"}, "kmm427pfbrc6rugtmbuli8j4q61u17uk", nil), + Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T06:00:00.000Z"}, "cjou7vscvp8ogv34d6vejootulqfn3jd", nil), + Entry("basal id", []string{"basal", "temp", "tools", "2014-06-11T09:00:00.000Z"}, "tn33bjb0241j9qh4jg9vdnf1g6k1g9r8", nil), + Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T19:00:00.000Z"}, "kftn188l8rjuvma3qkd3iqg34t0plajp", nil), ) }) }) From 74290b30f83a92f75f17ddf2b93862d083ad7b61 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 7 Aug 2024 17:26:23 +1200 Subject: [PATCH 383/413] try to find last upload if a legacy device --- .../deduplicator/device_deactivate_hash.go | 25 +++++++++++-------- data/store/mongo/mongo_data_set.go | 5 ++++ data/types/upload/upload.go | 1 + 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index f687b1ad06..33925e1f01 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -2,11 +2,14 @@ package deduplicator import ( "context" + "log" "github.com/tidepool-org/platform/data" dataStore "github.com/tidepool-org/platform/data/store" dataTypesUpload "github.com/tidepool-org/platform/data/types/upload" "github.com/tidepool-org/platform/errors" + "github.com/tidepool-org/platform/page" + "github.com/tidepool-org/platform/pointer" ) type DeviceDeactivateHashVersion string @@ -148,17 +151,17 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore opts := NewDefaultDeviceDeactivateHashOptions() if getDeviceDeactivateHashVersion(dataSet) == DeviceDeactivateHashVersionLegacy { - // TODO: find the last upload if there was one - // - // uploads, err := repository.GetDataSetsForUserByID(ctx, *dataSet.UserID, &dataStore.Filter{}, &page.Pagination{Page: 1, Size: 1}) - // if dataSetData == nil { - // return err - // } - // if len(uploads) != 0 { - // deviceDeactivateHashVersion = DeviceDeactivateHashVersionLegacy - // } - // NOTE: hard coded to test - opts = NewLegacyDeviceDeactivateHashOptions("7394e6ad03") + uploads, err := repository.ListUserDataSets(ctx, *dataSet.UserID, &data.DataSetFilter{IsLegacy: pointer.FromBool(true), DeviceID: dataSet.DeviceID}, &page.Pagination{Page: 1, Size: 1}) + if err == nil { + return errors.New("error getting datasets for user") + } + if len(uploads) != 0 { + log.Printf("DeviceDeactivateHash latest uploadID [%s] for device [%s]", *dataSet.DeviceID, *uploads[0].UploadID) + if uploads[0].LegacyGroupID != nil { + log.Printf("DeviceDeactivateHash latest upload groupID [%s]", *uploads[0].LegacyGroupID) + opts = NewLegacyDeviceDeactivateHashOptions(*uploads[0].LegacyGroupID) + } + } } if err := AssignDataSetDataIdentityHashes(dataSetData, opts); err != nil { diff --git a/data/store/mongo/mongo_data_set.go b/data/store/mongo/mongo_data_set.go index eadca16a91..081fced7ce 100644 --- a/data/store/mongo/mongo_data_set.go +++ b/data/store/mongo/mongo_data_set.go @@ -272,6 +272,11 @@ func (d *DataSetRepository) ListUserDataSets(ctx context.Context, userID string, if filter.DeviceID != nil { selector["deviceId"] = *filter.DeviceID } + + if filter.IsLegacy != nil && *filter.IsLegacy { + selector["_id"] = bson.M{"$not": bson.M{"$type": "objectId"}} + } + opts := storeStructuredMongo.FindWithPagination(pagination). SetSort(bson.M{"createdTime": -1}) cursor, err := d.Find(ctx, selector, opts) diff --git a/data/types/upload/upload.go b/data/types/upload/upload.go index b3b4780a95..2e4aa8c5e7 100644 --- a/data/types/upload/upload.go +++ b/data/types/upload/upload.go @@ -75,6 +75,7 @@ type Upload struct { State *string `json:"-" bson:"_state,omitempty"` // TODO: Should this be returned in JSON? I think so. TimeProcessing *string `json:"timeProcessing,omitempty" bson:"timeProcessing,omitempty"` Version *string `json:"version,omitempty" bson:"version,omitempty"` // TODO: Deprecate in favor of Client.Version + LegacyGroupID *string `json:"-" bson:"_groupId,omitempty"` } func NewUpload(parser structure.ObjectParser) *Upload { From c9ed224fe49239ee4df9f085ef75b223847b5fa2 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 7 Aug 2024 18:03:51 +1200 Subject: [PATCH 384/413] more error details --- data/deduplicator/deduplicator/device_deactivate_hash.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index 33925e1f01..c57466e6ef 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -151,9 +151,11 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore opts := NewDefaultDeviceDeactivateHashOptions() if getDeviceDeactivateHashVersion(dataSet) == DeviceDeactivateHashVersionLegacy { + log.Printf("DeviceDeactivateHash latest userID [%s] for device [%s]", *dataSet.UserID, *dataSet.DeviceID) + uploads, err := repository.ListUserDataSets(ctx, *dataSet.UserID, &data.DataSetFilter{IsLegacy: pointer.FromBool(true), DeviceID: dataSet.DeviceID}, &page.Pagination{Page: 1, Size: 1}) if err == nil { - return errors.New("error getting datasets for user") + return errors.Wrap(err, "error getting datasets for user") } if len(uploads) != 0 { log.Printf("DeviceDeactivateHash latest uploadID [%s] for device [%s]", *dataSet.DeviceID, *uploads[0].UploadID) From 7588edfadc6ac0ae44488cec5e1c0c3d72827c06 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 8 Aug 2024 07:41:16 +1200 Subject: [PATCH 385/413] debug --- data/deduplicator/deduplicator/device_deactivate_hash.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index c57466e6ef..e00f9a10ed 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -153,7 +153,13 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore if getDeviceDeactivateHashVersion(dataSet) == DeviceDeactivateHashVersionLegacy { log.Printf("DeviceDeactivateHash latest userID [%s] for device [%s]", *dataSet.UserID, *dataSet.DeviceID) - uploads, err := repository.ListUserDataSets(ctx, *dataSet.UserID, &data.DataSetFilter{IsLegacy: pointer.FromBool(true), DeviceID: dataSet.DeviceID}, &page.Pagination{Page: 1, Size: 1}) + filter := &data.DataSetFilter{IsLegacy: pointer.FromBool(true), DeviceID: dataSet.DeviceID} + pagination := &page.Pagination{Page: 1, Size: 1} + + log.Printf("DeviceDeactivateHash filter [%v]", filter) + log.Printf("DeviceDeactivateHash pagination [%v]", pagination) + + uploads, err := repository.ListUserDataSets(ctx, *dataSet.UserID, filter, pagination) if err == nil { return errors.Wrap(err, "error getting datasets for user") } From 1412b4c39aa381f4f6e747ecaf36013e0efd9844 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 8 Aug 2024 08:27:48 +1200 Subject: [PATCH 386/413] fix error check --- data/deduplicator/deduplicator/device_deactivate_hash.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index e00f9a10ed..1991b2f116 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -160,7 +160,8 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore log.Printf("DeviceDeactivateHash pagination [%v]", pagination) uploads, err := repository.ListUserDataSets(ctx, *dataSet.UserID, filter, pagination) - if err == nil { + if err != nil { + log.Printf("DeviceDeactivateHash ListUserDataSets error [%s]", err.Error()) return errors.Wrap(err, "error getting datasets for user") } if len(uploads) != 0 { From 079b214a4309ac438e8e6fc1bffa1e71b857e950 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 8 Aug 2024 15:58:29 +1200 Subject: [PATCH 387/413] allow checking based on _deduplicator cleanup logging --- .../deduplicator/device_deactivate_hash.go | 9 - .../verify/data_verify.go | 65 ++-- .../verify/data_verify_test.go | 34 +- .../verify/test/data_verify.go | 315 ++++++++++++++++++ .../verify/verify.go | 12 +- 5 files changed, 390 insertions(+), 45 deletions(-) diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index 1991b2f116..0419e8a827 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -2,7 +2,6 @@ package deduplicator import ( "context" - "log" "github.com/tidepool-org/platform/data" dataStore "github.com/tidepool-org/platform/data/store" @@ -151,23 +150,15 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore opts := NewDefaultDeviceDeactivateHashOptions() if getDeviceDeactivateHashVersion(dataSet) == DeviceDeactivateHashVersionLegacy { - log.Printf("DeviceDeactivateHash latest userID [%s] for device [%s]", *dataSet.UserID, *dataSet.DeviceID) - filter := &data.DataSetFilter{IsLegacy: pointer.FromBool(true), DeviceID: dataSet.DeviceID} pagination := &page.Pagination{Page: 1, Size: 1} - log.Printf("DeviceDeactivateHash filter [%v]", filter) - log.Printf("DeviceDeactivateHash pagination [%v]", pagination) - uploads, err := repository.ListUserDataSets(ctx, *dataSet.UserID, filter, pagination) if err != nil { - log.Printf("DeviceDeactivateHash ListUserDataSets error [%s]", err.Error()) return errors.Wrap(err, "error getting datasets for user") } if len(uploads) != 0 { - log.Printf("DeviceDeactivateHash latest uploadID [%s] for device [%s]", *dataSet.DeviceID, *uploads[0].UploadID) if uploads[0].LegacyGroupID != nil { - log.Printf("DeviceDeactivateHash latest upload groupID [%s]", *uploads[0].LegacyGroupID) opts = NewLegacyDeviceDeactivateHashOptions(*uploads[0].LegacyGroupID) } } diff --git a/migrations/20231128_jellyfish_migration/verify/data_verify.go b/migrations/20231128_jellyfish_migration/verify/data_verify.go index 3c29c5ec3e..cfafd27822 100644 --- a/migrations/20231128_jellyfish_migration/verify/data_verify.go +++ b/migrations/20231128_jellyfish_migration/verify/data_verify.go @@ -217,60 +217,62 @@ const ( PlatformExtra = "extra" PlatformDuplicate = "duplicate" PlatformMissing = "missing" + + CompareDatasetsDepuplicatorKey = "_deduplicator" + CompareDatasetsDeviceTimeKey = "deviceTime" ) -func CompareDatasets(platformSet []map[string]interface{}, jellyfishSet []map[string]interface{}) map[string][]map[string]interface{} { +func CompareDatasets(dataSet []map[string]interface{}, baseSet []map[string]interface{}, datumKeyName string) map[string][]map[string]interface{} { diffs := map[string][]map[string]interface{}{ PlatformExtra: {}, PlatformDuplicate: {}, PlatformMissing: {}, } - const deviceTimeName = "deviceTime" - type deviceTimeDatums map[string][]map[string]interface{} - pfCounts := deviceTimeDatums{} - jfCounts := deviceTimeDatums{} + type deviceDataMap map[string][]map[string]interface{} + + baseSetMap := deviceDataMap{} + dataSetCounts := deviceDataMap{} - for _, jDatum := range jellyfishSet { - strDatumTime := fmt.Sprintf("%v", jDatum[deviceTimeName]) + for _, datum := range baseSet { + datumKey := fmt.Sprintf("%v", datum[datumKeyName]) - if len(jfCounts[strDatumTime]) == 0 { - jfCounts[strDatumTime] = []map[string]interface{}{jDatum} - } else if len(jfCounts[strDatumTime]) >= 1 { - jfCounts[strDatumTime] = append(jfCounts[strDatumTime], jDatum) + if len(baseSetMap[datumKey]) == 0 { + baseSetMap[datumKey] = []map[string]interface{}{datum} + } else if len(baseSetMap[datumKey]) >= 1 { + baseSetMap[datumKey] = append(baseSetMap[datumKey], datum) } } - for _, pDatum := range platformSet { - - strDatumTime := fmt.Sprintf("%v", pDatum[deviceTimeName]) + for _, datum := range dataSet { + datumKey := fmt.Sprintf("%v", datum[datumKeyName]) - if len(pfCounts[strDatumTime]) == 0 { - pfCounts[strDatumTime] = []map[string]interface{}{pDatum} - } else if len(pfCounts[strDatumTime]) >= 1 { + if len(dataSetCounts[datumKey]) == 0 { + dataSetCounts[datumKey] = []map[string]interface{}{datum} + } else if len(dataSetCounts[datumKey]) >= 1 { - currentItems := pfCounts[strDatumTime] + currentItems := dataSetCounts[datumKey] for _, item := range currentItems { - if fmt.Sprintf("%v", item) == fmt.Sprintf("%v", pDatum) { - diffs[PlatformDuplicate] = append(diffs[PlatformDuplicate], pDatum) + if fmt.Sprintf("%v", item) == fmt.Sprintf("%v", datum) { + diffs[PlatformDuplicate] = append(diffs[PlatformDuplicate], datum) continue } else { - diffs[PlatformExtra] = append(diffs[PlatformExtra], pDatum) + diffs[PlatformExtra] = append(diffs[PlatformExtra], datum) break } } - pfCounts[strDatumTime] = append(pfCounts[strDatumTime], pDatum) + dataSetCounts[datumKey] = append(dataSetCounts[datumKey], datum) } - if len(jfCounts[fmt.Sprintf("%v", pDatum[deviceTimeName])]) == 0 { - diffs[PlatformExtra] = append(diffs[PlatformExtra], pDatum) + if len(baseSetMap[fmt.Sprintf("%v", datum[datumKeyName])]) == 0 { + diffs[PlatformExtra] = append(diffs[PlatformExtra], datum) } } - for jfDeviceTimeStr, jDatums := range jfCounts { - if len(pfCounts[jfDeviceTimeStr]) < len(jfCounts[jfDeviceTimeStr]) { + for datumKey, jDatums := range baseSetMap { + if len(dataSetCounts[datumKey]) < len(baseSetMap[datumKey]) { //NOTE: more of an indicator there are missing records ... - for i := len(pfCounts[jfDeviceTimeStr]); i < len(jfCounts[jfDeviceTimeStr]); i++ { + for i := len(dataSetCounts[datumKey]); i < len(baseSetMap[datumKey]); i++ { diffs[PlatformMissing] = append(diffs[PlatformMissing], jDatums[i]) } } @@ -285,7 +287,7 @@ var dataTypePathIgnored = map[string][]string{ "bolus": {"normal"}, } -func (m *DataVerify) VerifyAPIDifferences(platformUploadID string, jellyfishUploadID string, dataTyes []string) error { +func (m *DataVerify) VerifyUploadDifferences(platformUploadID string, jellyfishUploadID string, dataTyes []string, sameAccount bool) error { if len(dataTyes) == 0 { dataTyes = DatasetTypes @@ -307,7 +309,12 @@ func (m *DataVerify) VerifyAPIDifferences(platformUploadID string, jellyfishUplo pfSet := platformDataset[dType] comparePath := filepath.Join(".", "_compare", fmt.Sprintf("%s_%s", platformUploadID, jellyfishUploadID)) log.Printf("data written to %s", comparePath) - setDifferences := CompareDatasets(pfSet, jfSet) + + datumKeyName := CompareDatasetsDeviceTimeKey + if sameAccount { + datumKeyName = CompareDatasetsDepuplicatorKey + } + setDifferences := CompareDatasets(pfSet, jfSet, datumKeyName) if len(setDifferences[PlatformMissing]) > 0 { writeFileData(setDifferences[PlatformMissing], comparePath, fmt.Sprintf("%s_platform_missing.json", dType), true) } diff --git a/migrations/20231128_jellyfish_migration/verify/data_verify_test.go b/migrations/20231128_jellyfish_migration/verify/data_verify_test.go index c3dc274469..5e2b72965e 100644 --- a/migrations/20231128_jellyfish_migration/verify/data_verify_test.go +++ b/migrations/20231128_jellyfish_migration/verify/data_verify_test.go @@ -82,14 +82,14 @@ var _ = Describe("DataVerify", func() { var _ = Describe("CompareDatasets", func() { It("will have no differences when that same and no dups", func() { - dSetDifference := verify.CompareDatasets(test.JFBolusSet, test.JFBolusSet) + dSetDifference := verify.CompareDatasets(test.JFBolusSet, test.JFBolusSet, verify.CompareDatasetsDeviceTimeKey) Expect(len(dSetDifference[verify.PlatformDuplicate])).To(Equal(0)) Expect(len(dSetDifference[verify.PlatformExtra])).To(Equal(0)) Expect(len(dSetDifference[verify.PlatformMissing])).To(Equal(0)) }) It("will find duplicates in the platform dataset", func() { - dSetDifference := verify.CompareDatasets(test.PlatformBolusSet, test.JFBolusSet) + dSetDifference := verify.CompareDatasets(test.PlatformBolusSet, test.JFBolusSet, verify.CompareDatasetsDeviceTimeKey) Expect(len(dSetDifference[verify.PlatformDuplicate])).To(Equal(395)) Expect(len(dSetDifference[verify.PlatformExtra])).To(Equal(0)) Expect(len(dSetDifference[verify.PlatformMissing])).To(Equal(0)) @@ -101,7 +101,7 @@ var _ = Describe("DataVerify", func() { "deviceTime": "2018-01-03T13:07:10", } - dSetDifference := verify.CompareDatasets(append(test.PlatformBolusSet, duplicateTimeStamp), test.JFBolusSet) + dSetDifference := verify.CompareDatasets(append(test.PlatformBolusSet, duplicateTimeStamp), test.JFBolusSet, verify.CompareDatasetsDeviceTimeKey) Expect(len(dSetDifference[verify.PlatformDuplicate])).To(Equal(395)) Expect(len(dSetDifference[verify.PlatformExtra])).To(Equal(1)) Expect(len(dSetDifference[verify.PlatformMissing])).To(Equal(0)) @@ -113,7 +113,7 @@ var _ = Describe("DataVerify", func() { "deviceTime": "2023-01-18T12:00:00", } - dSetDifference := verify.CompareDatasets(append(test.PlatformBolusSet, expectedExtra), test.JFBolusSet) + dSetDifference := verify.CompareDatasets(append(test.PlatformBolusSet, expectedExtra), test.JFBolusSet, verify.CompareDatasetsDeviceTimeKey) Expect(len(dSetDifference[verify.PlatformDuplicate])).To(Equal(395)) Expect(len(dSetDifference[verify.PlatformExtra])).To(Equal(1)) Expect(dSetDifference[verify.PlatformExtra][0]).To(Equal(expectedExtra)) @@ -127,11 +127,35 @@ var _ = Describe("DataVerify", func() { Expect(len(platformBasals)).To(Equal(3123)) Expect(len(jellyfishBasals)).To(Equal(3386)) - dSetDifference := verify.CompareDatasets(platformBasals, jellyfishBasals) + dSetDifference := verify.CompareDatasets(platformBasals, jellyfishBasals, verify.CompareDatasetsDeviceTimeKey) Expect(len(dSetDifference[verify.PlatformDuplicate])).To(Equal(5)) Expect(len(dSetDifference[verify.PlatformExtra])).To(Equal(4)) Expect(len(dSetDifference[verify.PlatformMissing])).To(Equal(263)) }) + It("will find datums that are missing in the platform dataset with deduplicator key", func() { + platformSMBGs := test.GetPlatformSMBGData() + jfSMBGs := test.GetJellyfishSMBGData() + + Expect(len(platformSMBGs)).To(Equal(11)) + Expect(len(jfSMBGs)).To(Equal(11)) + + dSetDifference := verify.CompareDatasets(platformSMBGs, jfSMBGs, verify.CompareDatasetsDepuplicatorKey) + Expect(len(dSetDifference[verify.PlatformDuplicate])).To(Equal(0)) + Expect(len(dSetDifference[verify.PlatformExtra])).To(Equal(11)) + Expect(len(dSetDifference[verify.PlatformMissing])).To(Equal(11)) + }) + + It("will match when datasets are the same using with deduplicator key", func() { + smbgs := test.GetPlatformSMBGData() + + Expect(len(smbgs)).To(Equal(11)) + + dSetDifference := verify.CompareDatasets(smbgs, smbgs, verify.CompareDatasetsDepuplicatorKey) + Expect(len(dSetDifference[verify.PlatformDuplicate])).To(Equal(0)) + Expect(len(dSetDifference[verify.PlatformExtra])).To(Equal(0)) + Expect(len(dSetDifference[verify.PlatformMissing])).To(Equal(0)) + }) + }) }) diff --git a/migrations/20231128_jellyfish_migration/verify/test/data_verify.go b/migrations/20231128_jellyfish_migration/verify/test/data_verify.go index a089143b96..8a10be74b3 100644 --- a/migrations/20231128_jellyfish_migration/verify/test/data_verify.go +++ b/migrations/20231128_jellyfish_migration/verify/test/data_verify.go @@ -81403,3 +81403,318 @@ func GetPlatformBasalData() []map[string]interface{} { json.Unmarshal([]byte(platformBasalStr), &data) return data } + +var platformSMBG = `[ + { + "_active": true, + "_deduplicator": { "hash": "3757vg83cberlvf0mdpcsugf8epsqo3r" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-02-05T21:11:00", + "raw": { "units": "mg/dL", "value": 214 }, + "subType": "manual", + "time": "2023-02-06T06:11:00Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "b813ac02abe2633dccbe506da2f6a230", + "value": 11.8786 + }, + { + "_active": true, + "_deduplicator": { "hash": "9ulaq6mjosuemmonhot3g7si9hqh98g3" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-02-05T21:13:44", + "raw": { "units": "mg/dL", "value": 214 }, + "subType": "manual", + "time": "2023-02-06T06:13:44Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "b813ac02abe2633dccbe506da2f6a230", + "value": 11.8786 + }, + { + "_active": true, + "_deduplicator": { "hash": "a4hh520sh4c3mdr49831r5a99mvsodlv" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-02-05T21:29:16", + "raw": { "units": "mg/dL", "value": 196 }, + "subType": "manual", + "time": "2023-02-06T06:29:16Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "b813ac02abe2633dccbe506da2f6a230", + "value": 10.87947 + }, + { + "_active": true, + "_deduplicator": { "hash": "im31tbcq4nm945lef6fe6ouq1q1sd5il" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-02-05T21:29:27", + "raw": { "units": "mg/dL", "value": 196 }, + "subType": "manual", + "time": "2023-02-06T06:29:27Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "b813ac02abe2633dccbe506da2f6a230", + "value": 10.87947 + }, + { + "_active": true, + "_deduplicator": { "hash": "4g871fc9q184vu035va2tev67tjq4ff5" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-02-05T22:16:18", + "raw": { "units": "mg/dL", "value": 249 }, + "subType": "manual", + "time": "2023-02-06T07:16:18Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "b813ac02abe2633dccbe506da2f6a230", + "value": 13.82136 + }, + { + "_active": true, + "_deduplicator": { "hash": "ib5km8fru8gh3pe4hdqklk2avevh1mig" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-02-05T22:16:27", + "raw": { "units": "mg/dL", "value": 249 }, + "subType": "manual", + "time": "2023-02-06T07:16:27Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "b813ac02abe2633dccbe506da2f6a230", + "value": 13.82136 + }, + { + "_active": true, + "_deduplicator": { "hash": "n843tdkn1ebjtsuvcsi3clqg4r6jujp7" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-02-05T22:38:17", + "raw": { "units": "mg/dL", "value": 273 }, + "subType": "manual", + "time": "2023-02-06T07:38:17Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "b813ac02abe2633dccbe506da2f6a230", + "value": 15.15354 + }, + { + "_active": true, + "_deduplicator": { "hash": "anglvt19qpk2uagjir7ppoapjmffh9fu" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-03-27T07:38:59", + "raw": { "units": "mg/dL", "value": 135 }, + "subType": "manual", + "time": "2023-03-27T15:38:59Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "b813ac02abe2633dccbe506da2f6a230", + "value": 7.49351 + }, + { + "_active": true, + "_deduplicator": { "hash": "01p6pa28bec7i4fc9mburhii28ca63jg" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-04-10T10:54:40", + "raw": { "units": "mg/dL", "value": 212 }, + "subType": "manual", + "time": "2023-04-10T18:54:40Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "b813ac02abe2633dccbe506da2f6a230", + "value": 11.76759 + }, + { + "_active": true, + "_deduplicator": { "hash": "29nh08u6vjorr2u9h6va1sct36ik62fg" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-05-12T07:21:16", + "raw": { "units": "mg/dL", "value": 133 }, + "subType": "manual", + "time": "2023-05-12T15:21:16Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "b813ac02abe2633dccbe506da2f6a230", + "value": 7.38249 + }, + { + "_active": true, + "_deduplicator": { "hash": "iu7t9cj610evdrq7c3s3b1a0j7o868en" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-05-13T07:51:58", + "raw": { "units": "mg/dL", "value": 220 }, + "subType": "manual", + "time": "2023-05-13T15:51:58Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "b813ac02abe2633dccbe506da2f6a230", + "value": 12.21165 + } +]` + +var jfSMBG = `[ + { + "_active": true, + "_deduplicator": { "hash": "j4q9a6vhmjb5f7m1jic59u040rid9f8b" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-02-05T21:11:00", + "subType": "manual", + "time": "2023-02-06T06:11:00Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "upid_35d555132c1d", + "value": 11.878600700837442 + }, + { + "_active": true, + "_deduplicator": { "hash": "8ijj1jmphso7v6gro71ducposqktunuj" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-02-05T21:13:44", + "subType": "manual", + "time": "2023-02-06T06:13:44Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "upid_35d555132c1d", + "value": 11.878600700837442 + }, + { + "_active": true, + "_deduplicator": { "hash": "daftamn03o4bs9i4g69bj0vpe2iikm41" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-02-05T21:29:16", + "subType": "manual", + "time": "2023-02-06T06:29:16Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "upid_35d555132c1d", + "value": 10.879466062449245 + }, + { + "_active": true, + "_deduplicator": { "hash": "0q6de81ra2gvuik318bn8e2nfi2334n1" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-02-05T21:29:27", + "subType": "manual", + "time": "2023-02-06T06:29:27Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "upid_35d555132c1d", + "value": 10.879466062449245 + }, + { + "_active": true, + "_deduplicator": { "hash": "ve0vf4fn7g2l69geo888ptjbpd063ss3" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-02-05T22:16:18", + "subType": "manual", + "time": "2023-02-06T07:16:18Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "upid_35d555132c1d", + "value": 13.821362497703378 + }, + { + "_active": true, + "_deduplicator": { "hash": "tkba95oue98958d4426ct8fpld3vfe68" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-02-05T22:16:27", + "subType": "manual", + "time": "2023-02-06T07:16:27Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "upid_35d555132c1d", + "value": 13.821362497703378 + }, + { + "_active": true, + "_deduplicator": { "hash": "1volhr0dd869eicqaj292cgicucbm8jl" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-02-05T22:38:17", + "subType": "manual", + "time": "2023-02-06T07:38:17Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "upid_35d555132c1d", + "value": 15.153542015554306 + }, + { + "_active": true, + "_deduplicator": { "hash": "ro0m2jb88i36s7hu6kcm78d56lsdhipi" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-03-27T07:38:59", + "subType": "manual", + "time": "2023-03-27T15:38:59Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "upid_35d555132c1d", + "value": 7.49350978791147 + }, + { + "_active": true, + "_deduplicator": { "hash": "mlsuvb2v6hehl3ndg5r2kko7n5d3767a" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-04-10T10:54:40", + "subType": "manual", + "time": "2023-04-10T18:54:40Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "upid_35d555132c1d", + "value": 11.76758574101653 + }, + { + "_active": true, + "_deduplicator": { "hash": "pip6n51n6ai1fap1emaa3d0pi4890681" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-05-12T07:21:16", + "subType": "manual", + "time": "2023-05-12T15:21:16Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "upid_35d555132c1d", + "value": 7.382494828090559 + }, + { + "_active": true, + "_deduplicator": { "hash": "sbbhccl6snvsrv5bq3ks84n8i7vf8p3h" }, + "_userId": "6a452338-5064-4795-81ca-84957bad2280", + "deviceId": "some-device-id", + "deviceTime": "2023-05-13T07:51:58", + "subType": "manual", + "time": "2023-05-13T15:51:58Z", + "type": "smbg", + "units": "mmol/L", + "uploadId": "upid_35d555132c1d", + "value": 12.211645580300173 + } +]` + +func GetPlatformSMBGData() []map[string]interface{} { + data := []map[string]interface{}{} + json.Unmarshal([]byte(platformSMBG), &data) + return data +} + +func GetJellyfishSMBGData() []map[string]interface{} { + data := []map[string]interface{}{} + json.Unmarshal([]byte(jfSMBG), &data) + return data +} diff --git a/migrations/20231128_jellyfish_migration/verify/verify.go b/migrations/20231128_jellyfish_migration/verify/verify.go index a29e4b3409..af1c130f6e 100644 --- a/migrations/20231128_jellyfish_migration/verify/verify.go +++ b/migrations/20231128_jellyfish_migration/verify/verify.go @@ -24,6 +24,7 @@ type config struct { mongoURI string findBlobs bool verifyDeduped bool + sameAccount bool platformUploadID string jellyfishUploadID string uploadIdDeduped string @@ -33,6 +34,7 @@ type config struct { const MongoURIFlag = "uri" const PlatformUploadIDFlag = "upload-id-platform" const JellyfishUploadIDFlag = "upload-id-jellyfish" +const SameAccountFlag = "same-account" const FindBlobFlag = "find-blobs" const VerifyDedupedFlag = "verify-deduped" const UploadIdDedupedFlag = "upload-id" @@ -49,7 +51,7 @@ func main() { func NewVerifier(ctx context.Context) *Verify { return &Verify{ - config: &config{}, + config: &config{sameAccount: false}, ctx: ctx, cli: cli.NewApp(), } @@ -103,7 +105,7 @@ func (m *Verify) RunAndExit() { return fmt.Errorf("unable to create verification utils : %w", err) } - err = m.verificationUtil.VerifyAPIDifferences(m.config.platformUploadID, m.config.jellyfishUploadID, strings.Split(m.config.dataTypes, ",")) + err = m.verificationUtil.VerifyUploadDifferences(m.config.platformUploadID, m.config.jellyfishUploadID, strings.Split(m.config.dataTypes, ","), m.config.sameAccount) if err != nil { log.Printf("error running verify : %s", err.Error()) } @@ -140,6 +142,12 @@ func (m *Verify) Initialize() error { Destination: &m.config.jellyfishUploadID, Required: false, }, + cli.BoolFlag{ + Name: SameAccountFlag, + Usage: "the datasets are uploaded to the same account", + Destination: &m.config.sameAccount, + Required: false, + }, cli.StringFlag{ Name: UploadIdDedupedFlag, Usage: "uploadID of the dataset to check deduping of", From 6a71e3d07816197a35ca3f468380832dd869314f Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 8 Aug 2024 18:02:31 +1200 Subject: [PATCH 388/413] extend insulin range to 250 for consistency --- data/types/bolus/automated/automated.go | 2 +- data/types/bolus/automated/automated_test.go | 90 ++++---- data/types/bolus/combination/combination.go | 4 +- .../bolus/combination/combination_test.go | 218 +++++++++--------- data/types/bolus/extended/extended.go | 2 +- data/types/bolus/extended/extended_test.go | 94 ++++---- data/types/bolus/normal/normal.go | 2 +- data/types/bolus/normal/normal_test.go | 90 ++++---- data/types/calculator/calculator_test.go | 12 +- data/types/calculator/recommended.go | 10 +- data/types/calculator/recommended_test.go | 42 ++-- .../settings/pump/bolus_amount_maximum.go | 2 +- .../pump/bolus_amount_maximum_test.go | 20 +- 13 files changed, 294 insertions(+), 294 deletions(-) diff --git a/data/types/bolus/automated/automated.go b/data/types/bolus/automated/automated.go index ebca2c562b..43f5b9b76b 100644 --- a/data/types/bolus/automated/automated.go +++ b/data/types/bolus/automated/automated.go @@ -9,7 +9,7 @@ import ( const ( SubType = "automated" // TODO: Rename Type to "bolus/automated"; remove SubType - NormalMaximum = 100.0 + NormalMaximum = 250.0 NormalMinimum = 0.0 ) diff --git a/data/types/bolus/automated/automated_test.go b/data/types/bolus/automated/automated_test.go index a0bf5daf94..eb53062714 100644 --- a/data/types/bolus/automated/automated_test.go +++ b/data/types/bolus/automated/automated_test.go @@ -30,7 +30,7 @@ var _ = Describe("Automated", func() { }) It("NormalMaximum is expected", func() { - Expect(dataTypesBolusAutomated.NormalMaximum).To(Equal(100.0)) + Expect(dataTypesBolusAutomated.NormalMaximum).To(Equal(250.0)) }) It("NormalMinimum is expected", func() { @@ -143,7 +143,7 @@ var _ = Describe("Automated", func() { datum.NormalExpected = pointer.FromFloat64(-0.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, dataTypesBolusAutomated.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal missing; normal expected in range (lower)", func(datum *dataTypesBolusAutomated.Automated) { @@ -155,54 +155,54 @@ var _ = Describe("Automated", func() { Entry("normal missing; normal expected in range (upper)", func(datum *dataTypesBolusAutomated.Automated) { datum.Normal = nil - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.NormalExpected = pointer.FromFloat64(dataTypesBolusAutomated.NormalMaximum) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), ), Entry("normal missing; normal expected out of range (upper)", func(datum *dataTypesBolusAutomated.Automated) { datum.Normal = nil - datum.NormalExpected = pointer.FromFloat64(100.1) + datum.NormalExpected = pointer.FromFloat64(250.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(dataTypesBolusAutomated.NormalMaximum+0.1, 0.0, dataTypesBolusAutomated.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal out of range (lower); normal expected missing", func(datum *dataTypesBolusAutomated.Automated) { datum.Normal = pointer.FromFloat64(-0.1) datum.NormalExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, dataTypesBolusAutomated.NormalMaximum), "/normal", NewMeta()), ), Entry("normal out of range (lower); normal expected out of range (lower)", func(datum *dataTypesBolusAutomated.Automated) { datum.Normal = pointer.FromFloat64(-0.1) datum.NormalExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, dataTypesBolusAutomated.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, dataTypesBolusAutomated.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal out of range (lower); normal expected in range (lower)", func(datum *dataTypesBolusAutomated.Automated) { datum.Normal = pointer.FromFloat64(-0.1) datum.NormalExpected = pointer.FromFloat64(0.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, dataTypesBolusAutomated.NormalMaximum), "/normal", NewMeta()), ), Entry("normal out of range (lower); normal expected in range (upper)", func(datum *dataTypesBolusAutomated.Automated) { datum.Normal = pointer.FromFloat64(-0.1) - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.NormalExpected = pointer.FromFloat64(dataTypesBolusAutomated.NormalMaximum) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, dataTypesBolusAutomated.NormalMaximum), "/normal", NewMeta()), ), Entry("normal out of range (lower); normal expected out of range (upper)", func(datum *dataTypesBolusAutomated.Automated) { datum.Normal = pointer.FromFloat64(-0.1) - datum.NormalExpected = pointer.FromFloat64(100.1) + datum.NormalExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, dataTypesBolusAutomated.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(dataTypesBolusAutomated.NormalMaximum+0.1, 0.0, dataTypesBolusAutomated.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal in range (lower); normal expected missing", func(datum *dataTypesBolusAutomated.Automated) { @@ -216,7 +216,7 @@ var _ = Describe("Automated", func() { datum.Normal = pointer.FromFloat64(0.0) datum.NormalExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, dataTypesBolusAutomated.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal in range (lower); normal expected in range (lower)", func(datum *dataTypesBolusAutomated.Automated) { @@ -227,96 +227,96 @@ var _ = Describe("Automated", func() { Entry("normal in range (lower); normal expected in range (upper)", func(datum *dataTypesBolusAutomated.Automated) { datum.Normal = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.NormalExpected = pointer.FromFloat64(dataTypesBolusAutomated.NormalMaximum) }, ), Entry("normal in range (lower); normal expected out of range (upper)", func(datum *dataTypesBolusAutomated.Automated) { datum.Normal = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(100.1) + datum.NormalExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(dataTypesBolusAutomated.NormalMaximum+0.1, 0.0, dataTypesBolusAutomated.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal in range (upper); normal expected missing", func(datum *dataTypesBolusAutomated.Automated) { - datum.Normal = pointer.FromFloat64(100.0) + datum.Normal = pointer.FromFloat64(dataTypesBolusAutomated.NormalMaximum) datum.NormalExpected = nil }, ), Entry("normal in range (upper); normal expected out of range (lower)", func(datum *dataTypesBolusAutomated.Automated) { - datum.Normal = pointer.FromFloat64(100.0) - datum.NormalExpected = pointer.FromFloat64(99.9) + datum.Normal = pointer.FromFloat64(dataTypesBolusAutomated.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(249.9) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(99.9, 100.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(249.9, dataTypesBolusAutomated.NormalMaximum, dataTypesBolusAutomated.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal in range (upper); normal expected in range (lower)", func(datum *dataTypesBolusAutomated.Automated) { - datum.Normal = pointer.FromFloat64(100.0) - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.Normal = pointer.FromFloat64(dataTypesBolusAutomated.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(dataTypesBolusAutomated.NormalMaximum) }, ), Entry("normal in range (upper); normal expected in range (upper)", func(datum *dataTypesBolusAutomated.Automated) { - datum.Normal = pointer.FromFloat64(100.0) - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.Normal = pointer.FromFloat64(dataTypesBolusAutomated.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(dataTypesBolusAutomated.NormalMaximum) }, ), Entry("normal in range (upper); normal expected out of range (upper)", func(datum *dataTypesBolusAutomated.Automated) { - datum.Normal = pointer.FromFloat64(100.0) - datum.NormalExpected = pointer.FromFloat64(100.1) + datum.Normal = pointer.FromFloat64(dataTypesBolusAutomated.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 100.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(dataTypesBolusAutomated.NormalMaximum+0.1, dataTypesBolusAutomated.NormalMaximum, dataTypesBolusAutomated.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal out of range (upper); normal expected missing", func(datum *dataTypesBolusAutomated.Automated) { - datum.Normal = pointer.FromFloat64(100.1) + datum.Normal = pointer.FromFloat64(250.1) datum.NormalExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(dataTypesBolusAutomated.NormalMaximum+0.1, 0.0, dataTypesBolusAutomated.NormalMaximum), "/normal", NewMeta()), ), Entry("normal out of range (upper); normal expected out of range (lower)", func(datum *dataTypesBolusAutomated.Automated) { - datum.Normal = pointer.FromFloat64(100.1) + datum.Normal = pointer.FromFloat64(250.1) datum.NormalExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(dataTypesBolusAutomated.NormalMaximum+0.1, 0.0, dataTypesBolusAutomated.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, dataTypesBolusAutomated.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal out of range (upper); normal expected in range (lower)", func(datum *dataTypesBolusAutomated.Automated) { - datum.Normal = pointer.FromFloat64(100.1) + datum.Normal = pointer.FromFloat64(250.1) datum.NormalExpected = pointer.FromFloat64(0.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(dataTypesBolusAutomated.NormalMaximum+0.1, 0.0, dataTypesBolusAutomated.NormalMaximum), "/normal", NewMeta()), ), Entry("normal out of range (upper); normal expected in range (upper)", func(datum *dataTypesBolusAutomated.Automated) { - datum.Normal = pointer.FromFloat64(100.1) - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.Normal = pointer.FromFloat64(250.1) + datum.NormalExpected = pointer.FromFloat64(dataTypesBolusAutomated.NormalMaximum) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(dataTypesBolusAutomated.NormalMaximum+0.1, 0.0, dataTypesBolusAutomated.NormalMaximum), "/normal", NewMeta()), ), Entry("normal out of range (upper); normal expected out of range (upper)", func(datum *dataTypesBolusAutomated.Automated) { - datum.Normal = pointer.FromFloat64(100.1) - datum.NormalExpected = pointer.FromFloat64(100.1) + datum.Normal = pointer.FromFloat64(250.1) + datum.NormalExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(dataTypesBolusAutomated.NormalMaximum+0.1, 0.0, dataTypesBolusAutomated.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(dataTypesBolusAutomated.NormalMaximum+0.1, 0.0, dataTypesBolusAutomated.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("multiple errors", func(datum *dataTypesBolusAutomated.Automated) { datum.Type = "invalidType" datum.SubType = "invalidSubType" datum.Normal = nil - datum.NormalExpected = pointer.FromFloat64(100.1) + datum.NormalExpected = pointer.FromFloat64(250.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidType", "bolus"), "/type", &dataTypesBolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidSubType", "automated"), "/subType", &dataTypesBolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", &dataTypesBolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedNormal", &dataTypesBolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(dataTypesBolusAutomated.NormalMaximum+0.1, 0.0, dataTypesBolusAutomated.NormalMaximum), "/expectedNormal", &dataTypesBolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), ), ) }) diff --git a/data/types/bolus/combination/combination.go b/data/types/bolus/combination/combination.go index e670253179..19ca3dab69 100644 --- a/data/types/bolus/combination/combination.go +++ b/data/types/bolus/combination/combination.go @@ -11,9 +11,9 @@ const ( DurationMaximum = 86400000 DurationMinimum = 0 - ExtendedMaximum = 100.0 + ExtendedMaximum = 250.0 ExtendedMinimum = 0.0 - NormalMaximum = 100.0 + NormalMaximum = 250.0 NormalMinimum = 0.0 ) diff --git a/data/types/bolus/combination/combination_test.go b/data/types/bolus/combination/combination_test.go index ba376711bb..feec5f4741 100644 --- a/data/types/bolus/combination/combination_test.go +++ b/data/types/bolus/combination/combination_test.go @@ -37,7 +37,7 @@ var _ = Describe("Combination", func() { }) It("ExtendedMaximum is expected", func() { - Expect(combination.ExtendedMaximum).To(Equal(100.0)) + Expect(combination.ExtendedMaximum).To(Equal(250.0)) }) It("ExtendedMinimum is expected", func() { @@ -45,7 +45,7 @@ var _ = Describe("Combination", func() { }) It("NormalMaximum is expected", func() { - Expect(combination.NormalMaximum).To(Equal(100.0)) + Expect(combination.NormalMaximum).To(Equal(250.0)) }) It("NormalMinimum is expected", func() { @@ -298,7 +298,7 @@ var _ = Describe("Combination", func() { datum.ExtendedExpected = pointer.FromFloat64(-0.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedExtended", NewMeta()), ), Entry("normal expected missing; extended missing; extended expected in range (lower)", func(datum *combination.Combination) { @@ -310,17 +310,17 @@ var _ = Describe("Combination", func() { Entry("normal expected missing; extended missing; extended expected in range (upper)", func(datum *combination.Combination) { datum.Extended = nil - datum.ExtendedExpected = pointer.FromFloat64(100.0) + datum.ExtendedExpected = pointer.FromFloat64(250.0) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), ), Entry("normal expected missing; extended missing; extended expected out of range (upper)", func(datum *combination.Combination) { datum.Extended = nil - datum.ExtendedExpected = pointer.FromFloat64(100.1) + datum.ExtendedExpected = pointer.FromFloat64(250.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedExtended", NewMeta()), ), Entry("normal expected missing; extended out of range (lower); extended expected missing", func(datum *combination.Combination) { @@ -328,37 +328,37 @@ var _ = Describe("Combination", func() { datum.Extended = pointer.FromFloat64(-0.1) datum.ExtendedExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/extended", NewMeta()), ), Entry("normal expected missing; extended out of range (lower); extended expected out of range (lower)", func(datum *combination.Combination) { datum.Extended = pointer.FromFloat64(-0.1) datum.ExtendedExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedExtended", NewMeta()), ), Entry("normal expected missing; extended out of range (lower); extended expected in range (lower)", func(datum *combination.Combination) { datum.Extended = pointer.FromFloat64(-0.1) datum.ExtendedExpected = pointer.FromFloat64(0.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/extended", NewMeta()), ), Entry("normal expected missing; extended out of range (lower); extended expected in range (upper)", func(datum *combination.Combination) { datum.Extended = pointer.FromFloat64(-0.1) - datum.ExtendedExpected = pointer.FromFloat64(100.0) + datum.ExtendedExpected = pointer.FromFloat64(250.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/extended", NewMeta()), ), Entry("normal expected missing; extended out of range (lower); extended expected out of range (upper)", func(datum *combination.Combination) { datum.Extended = pointer.FromFloat64(-0.1) - datum.ExtendedExpected = pointer.FromFloat64(100.1) + datum.ExtendedExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedExtended", NewMeta()), ), Entry("normal expected missing; extended in range (lower); extended expected missing", func(datum *combination.Combination) { @@ -373,7 +373,7 @@ var _ = Describe("Combination", func() { datum.Extended = pointer.FromFloat64(0.0) datum.ExtendedExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedExtended", NewMeta()), ), Entry("normal expected missing; extended in range (lower); extended expected in range (lower)", func(datum *combination.Combination) { @@ -384,86 +384,86 @@ var _ = Describe("Combination", func() { Entry("normal expected missing; extended in range (lower); extended expected in range (upper)", func(datum *combination.Combination) { datum.Extended = pointer.FromFloat64(0.0) - datum.ExtendedExpected = pointer.FromFloat64(100.0) + datum.ExtendedExpected = pointer.FromFloat64(250.0) }, ), Entry("normal expected missing; extended in range (lower); extended expected out of range (upper)", func(datum *combination.Combination) { datum.Extended = pointer.FromFloat64(0.0) - datum.ExtendedExpected = pointer.FromFloat64(100.1) + datum.ExtendedExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedExtended", NewMeta()), ), Entry("normal expected missing; extended in range (upper); extended expected missing", func(datum *combination.Combination) { datum.DurationExpected = nil - datum.Extended = pointer.FromFloat64(100.0) + datum.Extended = pointer.FromFloat64(250.0) datum.ExtendedExpected = nil }, ), Entry("normal expected missing; extended in range (upper); extended expected out of range (lower)", func(datum *combination.Combination) { - datum.Extended = pointer.FromFloat64(100.0) - datum.ExtendedExpected = pointer.FromFloat64(99.9) + datum.Extended = pointer.FromFloat64(250.0) + datum.ExtendedExpected = pointer.FromFloat64(249.9) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(99.9, 100.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(249.9, 250.0, 250.0), "/expectedExtended", NewMeta()), ), Entry("normal expected missing; extended in range (upper); extended expected in range (lower)", func(datum *combination.Combination) { - datum.Extended = pointer.FromFloat64(100.0) - datum.ExtendedExpected = pointer.FromFloat64(100.0) + datum.Extended = pointer.FromFloat64(250.0) + datum.ExtendedExpected = pointer.FromFloat64(250.0) }, ), Entry("normal expected missing; extended in range (upper); extended expected in range (upper)", func(datum *combination.Combination) { - datum.Extended = pointer.FromFloat64(100.0) - datum.ExtendedExpected = pointer.FromFloat64(100.0) + datum.Extended = pointer.FromFloat64(250.0) + datum.ExtendedExpected = pointer.FromFloat64(250.0) }, ), Entry("normal expected missing; extended in range (upper); extended expected out of range (upper)", func(datum *combination.Combination) { - datum.Extended = pointer.FromFloat64(100.0) - datum.ExtendedExpected = pointer.FromFloat64(100.1) + datum.Extended = pointer.FromFloat64(250.0) + datum.ExtendedExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 100.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 250.0, 250.0), "/expectedExtended", NewMeta()), ), Entry("normal expected missing; extended out of range (upper); extended expected missing", func(datum *combination.Combination) { datum.DurationExpected = nil - datum.Extended = pointer.FromFloat64(100.1) + datum.Extended = pointer.FromFloat64(250.1) datum.ExtendedExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/extended", NewMeta()), ), Entry("normal expected missing; extended out of range (upper); extended expected out of range (lower)", func(datum *combination.Combination) { - datum.Extended = pointer.FromFloat64(100.1) + datum.Extended = pointer.FromFloat64(250.1) datum.ExtendedExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedExtended", NewMeta()), ), Entry("normal expected missing; extended out of range (upper); extended expected in range (lower)", func(datum *combination.Combination) { - datum.Extended = pointer.FromFloat64(100.1) + datum.Extended = pointer.FromFloat64(250.1) datum.ExtendedExpected = pointer.FromFloat64(0.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/extended", NewMeta()), ), Entry("normal expected missing; extended out of range (upper); extended expected in range (upper)", func(datum *combination.Combination) { - datum.Extended = pointer.FromFloat64(100.1) - datum.ExtendedExpected = pointer.FromFloat64(100.0) + datum.Extended = pointer.FromFloat64(250.1) + datum.ExtendedExpected = pointer.FromFloat64(250.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/extended", NewMeta()), ), Entry("normal expected missing; extended out of range (upper); extended expected out of range (upper)", func(datum *combination.Combination) { - datum.Extended = pointer.FromFloat64(100.1) - datum.ExtendedExpected = pointer.FromFloat64(100.1) + datum.Extended = pointer.FromFloat64(250.1) + datum.ExtendedExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedExtended", NewMeta()), ), Entry("normal expected missing; duration missing; extended expected missing", func(datum *combination.Combination) { @@ -697,7 +697,7 @@ var _ = Describe("Combination", func() { datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedExtended", NewMeta()), ), Entry("normal expected exists; extended missing; extended expected in range (lower)", func(datum *combination.Combination) { @@ -712,7 +712,7 @@ var _ = Describe("Combination", func() { func(datum *combination.Combination) { datum.Duration = pointer.FromInt(0) datum.Extended = nil - datum.ExtendedExpected = pointer.FromFloat64(100.0) + datum.ExtendedExpected = pointer.FromFloat64(250.0) datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), @@ -721,11 +721,11 @@ var _ = Describe("Combination", func() { func(datum *combination.Combination) { datum.Duration = pointer.FromInt(0) datum.Extended = nil - datum.ExtendedExpected = pointer.FromFloat64(100.1) + datum.ExtendedExpected = pointer.FromFloat64(250.1) datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedExtended", NewMeta()), ), Entry("normal expected exists; extended out of range (lower); extended expected missing", func(datum *combination.Combination) { @@ -745,7 +745,7 @@ var _ = Describe("Combination", func() { datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(-0.1, 0.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedExtended", NewMeta()), ), Entry("normal expected exists; extended out of range (lower); extended expected in range (lower)", func(datum *combination.Combination) { @@ -760,7 +760,7 @@ var _ = Describe("Combination", func() { func(datum *combination.Combination) { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(-0.1) - datum.ExtendedExpected = pointer.FromFloat64(100.0) + datum.ExtendedExpected = pointer.FromFloat64(250.0) datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(-0.1, 0.0), "/extended", NewMeta()), @@ -769,11 +769,11 @@ var _ = Describe("Combination", func() { func(datum *combination.Combination) { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(-0.1) - datum.ExtendedExpected = pointer.FromFloat64(100.1) + datum.ExtendedExpected = pointer.FromFloat64(250.1) datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(-0.1, 0.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedExtended", NewMeta()), ), Entry("normal expected exists; extended in range; extended expected missing", func(datum *combination.Combination) { @@ -791,7 +791,7 @@ var _ = Describe("Combination", func() { datum.ExtendedExpected = pointer.FromFloat64(-0.1) datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0, 250.0), "/expectedExtended", NewMeta()), ), Entry("normal expected exists; extended in range; extended expected in range (lower)", func(datum *combination.Combination) { @@ -805,7 +805,7 @@ var _ = Describe("Combination", func() { func(datum *combination.Combination) { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.0) - datum.ExtendedExpected = pointer.FromFloat64(100.0) + datum.ExtendedExpected = pointer.FromFloat64(250.0) datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) }, ), @@ -813,10 +813,10 @@ var _ = Describe("Combination", func() { func(datum *combination.Combination) { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.0) - datum.ExtendedExpected = pointer.FromFloat64(100.1) + datum.ExtendedExpected = pointer.FromFloat64(250.1) datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0, 250.0), "/expectedExtended", NewMeta()), ), Entry("normal expected exists; extended out of range (upper); extended expected missing", func(datum *combination.Combination) { @@ -836,7 +836,7 @@ var _ = Describe("Combination", func() { datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(0.1, 0.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedExtended", NewMeta()), ), Entry("normal expected exists; extended out of range (upper); extended expected in range (lower)", func(datum *combination.Combination) { @@ -851,7 +851,7 @@ var _ = Describe("Combination", func() { func(datum *combination.Combination) { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.1) - datum.ExtendedExpected = pointer.FromFloat64(100.0) + datum.ExtendedExpected = pointer.FromFloat64(250.0) datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(0.1, 0.0), "/extended", NewMeta()), @@ -860,11 +860,11 @@ var _ = Describe("Combination", func() { func(datum *combination.Combination) { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.1) - datum.ExtendedExpected = pointer.FromFloat64(100.1) + datum.ExtendedExpected = pointer.FromFloat64(250.1) datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(0.1, 0.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedExtended", NewMeta()), ), Entry("normal in range (lower); extended in range (lower); normal expected in range (lower); extended expected out of range (lower)", func(datum *combination.Combination) { @@ -890,7 +890,7 @@ var _ = Describe("Combination", func() { datum.NormalExpected = pointer.FromFloat64(-0.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedNormal", NewMeta()), ), Entry("normal missing; normal expected in range (lower)", func(datum *combination.Combination) { @@ -906,7 +906,7 @@ var _ = Describe("Combination", func() { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.0) datum.Normal = nil - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.NormalExpected = pointer.FromFloat64(250.0) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), ), @@ -915,17 +915,17 @@ var _ = Describe("Combination", func() { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.0) datum.Normal = nil - datum.NormalExpected = pointer.FromFloat64(100.1) + datum.NormalExpected = pointer.FromFloat64(250.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedNormal", NewMeta()), ), Entry("normal out of range (lower); normal expected missing", func(datum *combination.Combination) { datum.Normal = pointer.FromFloat64(-0.1) datum.NormalExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/normal", NewMeta()), ), Entry("normal out of range (lower); normal expected out of range (lower)", func(datum *combination.Combination) { @@ -934,8 +934,8 @@ var _ = Describe("Combination", func() { datum.Normal = pointer.FromFloat64(-0.1) datum.NormalExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedNormal", NewMeta()), ), Entry("normal out of range (lower); normal expected in range (lower)", func(datum *combination.Combination) { @@ -944,26 +944,26 @@ var _ = Describe("Combination", func() { datum.Normal = pointer.FromFloat64(-0.1) datum.NormalExpected = pointer.FromFloat64(0.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/normal", NewMeta()), ), Entry("normal out of range (lower); normal expected in range (upper)", func(datum *combination.Combination) { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.0) datum.Normal = pointer.FromFloat64(-0.1) - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.NormalExpected = pointer.FromFloat64(250.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/normal", NewMeta()), ), Entry("normal out of range (lower); normal expected out of range (upper)", func(datum *combination.Combination) { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.0) datum.Normal = pointer.FromFloat64(-0.1) - datum.NormalExpected = pointer.FromFloat64(100.1) + datum.NormalExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedNormal", NewMeta()), ), Entry("normal in range (lower); normal expected missing, extended missing", func(datum *combination.Combination) { @@ -1026,7 +1026,7 @@ var _ = Describe("Combination", func() { datum.Normal = pointer.FromFloat64(0.0) datum.NormalExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedNormal", NewMeta()), ), Entry("normal in range (lower); normal expected in range (lower)", func(datum *combination.Combination) { @@ -1041,7 +1041,7 @@ var _ = Describe("Combination", func() { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.0) datum.Normal = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.NormalExpected = pointer.FromFloat64(250.0) }, ), Entry("normal in range (lower); normal expected out of range (upper)", @@ -1049,13 +1049,13 @@ var _ = Describe("Combination", func() { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.0) datum.Normal = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(100.1) + datum.NormalExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedNormal", NewMeta()), ), Entry("normal in range (upper); normal expected missing", func(datum *combination.Combination) { - datum.Normal = pointer.FromFloat64(100.0) + datum.Normal = pointer.FromFloat64(250.0) datum.NormalExpected = nil }, ), @@ -1063,87 +1063,87 @@ var _ = Describe("Combination", func() { func(datum *combination.Combination) { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(100.0) - datum.NormalExpected = pointer.FromFloat64(99.9) + datum.Normal = pointer.FromFloat64(250.0) + datum.NormalExpected = pointer.FromFloat64(249.9) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(99.9, 100.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(249.9, 250.0, 250.0), "/expectedNormal", NewMeta()), ), Entry("normal in range (upper); normal expected in range (lower)", func(datum *combination.Combination) { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(100.0) - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.Normal = pointer.FromFloat64(250.0) + datum.NormalExpected = pointer.FromFloat64(250.0) }, ), Entry("normal in range (upper); normal expected in range (upper)", func(datum *combination.Combination) { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(100.0) - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.Normal = pointer.FromFloat64(250.0) + datum.NormalExpected = pointer.FromFloat64(250.0) }, ), Entry("normal in range (upper); normal expected out of range (upper)", func(datum *combination.Combination) { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(100.0) - datum.NormalExpected = pointer.FromFloat64(100.1) + datum.Normal = pointer.FromFloat64(250.0) + datum.NormalExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 100.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 250.0, 250.0), "/expectedNormal", NewMeta()), ), Entry("normal out of range (upper); normal expected missing", func(datum *combination.Combination) { - datum.Normal = pointer.FromFloat64(100.1) + datum.Normal = pointer.FromFloat64(250.1) datum.NormalExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/normal", NewMeta()), ), Entry("normal out of range (upper); normal expected out of range (lower)", func(datum *combination.Combination) { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(100.1) + datum.Normal = pointer.FromFloat64(250.1) datum.NormalExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedNormal", NewMeta()), ), Entry("normal out of range (upper); normal expected in range (lower)", func(datum *combination.Combination) { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(100.1) + datum.Normal = pointer.FromFloat64(250.1) datum.NormalExpected = pointer.FromFloat64(0.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/normal", NewMeta()), ), Entry("normal out of range (upper); normal expected in range (upper)", func(datum *combination.Combination) { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(100.1) - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.Normal = pointer.FromFloat64(250.1) + datum.NormalExpected = pointer.FromFloat64(250.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/normal", NewMeta()), ), Entry("normal out of range (upper); normal expected out of range (upper)", func(datum *combination.Combination) { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(100.1) - datum.NormalExpected = pointer.FromFloat64(100.1) + datum.Normal = pointer.FromFloat64(250.1) + datum.NormalExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedNormal", NewMeta()), ), Entry("allow normal and extended to be 0 when extended expected is missing", func(datum *combination.Combination) { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.0) datum.Normal = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.NormalExpected = pointer.FromFloat64(250.0) datum.ExtendedExpected = nil }, ), @@ -1153,7 +1153,7 @@ var _ = Describe("Combination", func() { datum.Extended = pointer.FromFloat64(0.0) datum.Normal = pointer.FromFloat64(0.0) datum.NormalExpected = nil - datum.ExtendedExpected = pointer.FromFloat64(100.0) + datum.ExtendedExpected = pointer.FromFloat64(250.0) }, ), Entry("allow normal and extended to be 0 when both normal expected and extended expected are in range", @@ -1161,7 +1161,7 @@ var _ = Describe("Combination", func() { datum.Duration = pointer.FromInt(0) datum.Extended = pointer.FromFloat64(0.0) datum.Normal = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.NormalExpected = pointer.FromFloat64(250.0) }, ), Entry("multiple errors", @@ -1171,18 +1171,18 @@ var _ = Describe("Combination", func() { datum.Duration = nil datum.DurationExpected = pointer.FromInt(86400001) datum.Extended = nil - datum.ExtendedExpected = pointer.FromFloat64(100.1) + datum.ExtendedExpected = pointer.FromFloat64(250.1) datum.Normal = nil - datum.NormalExpected = pointer.FromFloat64(100.1) + datum.NormalExpected = pointer.FromFloat64(250.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidType", "bolus"), "/type", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidSubType", "dual/square"), "/subType", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/expectedDuration", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0, 100), "/expectedExtended", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0, 250), "/expectedExtended", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0, 100), "/expectedNormal", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0, 250), "/expectedNormal", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), ), ) }) diff --git a/data/types/bolus/extended/extended.go b/data/types/bolus/extended/extended.go index 5a0dbf694f..a843de25fd 100644 --- a/data/types/bolus/extended/extended.go +++ b/data/types/bolus/extended/extended.go @@ -11,7 +11,7 @@ const ( DurationMaximum = 86400000 DurationMinimum = 0 - ExtendedMaximum = 100.0 + ExtendedMaximum = 250.0 ExtendedMinimum = 0.0 ) diff --git a/data/types/bolus/extended/extended_test.go b/data/types/bolus/extended/extended_test.go index a7b4e55c54..60c126488a 100644 --- a/data/types/bolus/extended/extended_test.go +++ b/data/types/bolus/extended/extended_test.go @@ -36,7 +36,7 @@ var _ = Describe("Extended", func() { }) It("ExtendedMaximum is expected", func() { - Expect(extended.ExtendedMaximum).To(Equal(100.0)) + Expect(extended.ExtendedMaximum).To(Equal(250.0)) }) It("ExtendedMinimum is expected", func() { @@ -288,7 +288,7 @@ var _ = Describe("Extended", func() { datum.ExtendedExpected = pointer.FromFloat64(-0.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), ), Entry("extended missing; extended expected in range (lower)", func(datum *extended.Extended) { @@ -300,17 +300,17 @@ var _ = Describe("Extended", func() { Entry("extended missing; extended expected in range (upper)", func(datum *extended.Extended) { datum.Extended = nil - datum.ExtendedExpected = pointer.FromFloat64(100.0) + datum.ExtendedExpected = pointer.FromFloat64(extended.ExtendedMaximum) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), ), Entry("extended missing; extended expected out of range (upper)", func(datum *extended.Extended) { datum.Extended = nil - datum.ExtendedExpected = pointer.FromFloat64(100.1) + datum.ExtendedExpected = pointer.FromFloat64(250.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), ), Entry("extended out of range (lower); extended expected missing", func(datum *extended.Extended) { @@ -318,37 +318,37 @@ var _ = Describe("Extended", func() { datum.Extended = pointer.FromFloat64(-0.1) datum.ExtendedExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), ), Entry("extended out of range (lower); extended expected out of range (lower)", func(datum *extended.Extended) { datum.Extended = pointer.FromFloat64(-0.1) datum.ExtendedExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), ), Entry("extended out of range (lower); extended expected in range (lower)", func(datum *extended.Extended) { datum.Extended = pointer.FromFloat64(-0.1) datum.ExtendedExpected = pointer.FromFloat64(0.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), ), Entry("extended out of range (lower); extended expected in range (upper)", func(datum *extended.Extended) { datum.Extended = pointer.FromFloat64(-0.1) - datum.ExtendedExpected = pointer.FromFloat64(100.0) + datum.ExtendedExpected = pointer.FromFloat64(extended.ExtendedMaximum) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), ), Entry("extended out of range (lower); extended expected out of range (upper)", func(datum *extended.Extended) { datum.Extended = pointer.FromFloat64(-0.1) - datum.ExtendedExpected = pointer.FromFloat64(100.1) + datum.ExtendedExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), ), Entry("extended in range (lower); extended expected missing", func(datum *extended.Extended) { @@ -363,7 +363,7 @@ var _ = Describe("Extended", func() { datum.Extended = pointer.FromFloat64(0.0) datum.ExtendedExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), ), Entry("extended in range (lower); extended expected in range (lower)", func(datum *extended.Extended) { @@ -374,86 +374,86 @@ var _ = Describe("Extended", func() { Entry("extended in range (lower); extended expected in range (upper)", func(datum *extended.Extended) { datum.Extended = pointer.FromFloat64(0.0) - datum.ExtendedExpected = pointer.FromFloat64(100.0) + datum.ExtendedExpected = pointer.FromFloat64(extended.ExtendedMaximum) }, ), Entry("extended in range (lower); extended expected out of range (upper)", func(datum *extended.Extended) { datum.Extended = pointer.FromFloat64(0.0) - datum.ExtendedExpected = pointer.FromFloat64(100.1) + datum.ExtendedExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), ), Entry("extended in range (upper); extended expected missing", func(datum *extended.Extended) { datum.DurationExpected = nil - datum.Extended = pointer.FromFloat64(100.0) + datum.Extended = pointer.FromFloat64(extended.ExtendedMaximum) datum.ExtendedExpected = nil }, ), Entry("extended in range (upper); extended expected out of range (lower)", func(datum *extended.Extended) { - datum.Extended = pointer.FromFloat64(100.0) - datum.ExtendedExpected = pointer.FromFloat64(99.9) + datum.Extended = pointer.FromFloat64(extended.ExtendedMaximum) + datum.ExtendedExpected = pointer.FromFloat64(249.9) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(99.9, 100.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(249.9, extended.ExtendedMaximum, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), ), Entry("extended in range (upper); extended expected in range (lower)", func(datum *extended.Extended) { - datum.Extended = pointer.FromFloat64(100.0) - datum.ExtendedExpected = pointer.FromFloat64(100.0) + datum.Extended = pointer.FromFloat64(extended.ExtendedMaximum) + datum.ExtendedExpected = pointer.FromFloat64(extended.ExtendedMaximum) }, ), Entry("extended in range (upper); extended expected in range (upper)", func(datum *extended.Extended) { - datum.Extended = pointer.FromFloat64(100.0) - datum.ExtendedExpected = pointer.FromFloat64(100.0) + datum.Extended = pointer.FromFloat64(extended.ExtendedMaximum) + datum.ExtendedExpected = pointer.FromFloat64(extended.ExtendedMaximum) }, ), Entry("extended in range (upper); extended expected out of range (upper)", func(datum *extended.Extended) { - datum.Extended = pointer.FromFloat64(100.0) - datum.ExtendedExpected = pointer.FromFloat64(100.1) + datum.Extended = pointer.FromFloat64(extended.ExtendedMaximum) + datum.ExtendedExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 100.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, extended.ExtendedMaximum, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), ), Entry("extended out of range (upper); extended expected missing", func(datum *extended.Extended) { datum.DurationExpected = nil - datum.Extended = pointer.FromFloat64(100.1) + datum.Extended = pointer.FromFloat64(250.1) datum.ExtendedExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), ), Entry("extended out of range (upper); extended expected out of range (lower)", func(datum *extended.Extended) { - datum.Extended = pointer.FromFloat64(100.1) + datum.Extended = pointer.FromFloat64(250.1) datum.ExtendedExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), ), Entry("extended out of range (upper); extended expected in range (lower)", func(datum *extended.Extended) { - datum.Extended = pointer.FromFloat64(100.1) + datum.Extended = pointer.FromFloat64(250.1) datum.ExtendedExpected = pointer.FromFloat64(0.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), ), Entry("extended out of range (upper); extended expected in range (upper)", func(datum *extended.Extended) { - datum.Extended = pointer.FromFloat64(100.1) - datum.ExtendedExpected = pointer.FromFloat64(100.0) + datum.Extended = pointer.FromFloat64(250.1) + datum.ExtendedExpected = pointer.FromFloat64(extended.ExtendedMaximum) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), ), Entry("extended out of range (upper); extended expected out of range (upper)", func(datum *extended.Extended) { - datum.Extended = pointer.FromFloat64(100.1) - datum.ExtendedExpected = pointer.FromFloat64(100.1) + datum.Extended = pointer.FromFloat64(250.1) + datum.ExtendedExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), ), Entry("duration missing; extended expected missing", @@ -465,7 +465,7 @@ var _ = Describe("Extended", func() { Entry("duration missing; extended expected exists", func(datum *extended.Extended) { datum.DurationExpected = nil - datum.ExtendedExpected = pointer.FromFloat64(100.0) + datum.ExtendedExpected = pointer.FromFloat64(extended.ExtendedMaximum) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/expectedDuration", NewMeta()), ), @@ -479,7 +479,7 @@ var _ = Describe("Extended", func() { Entry("duration exists; extended expected exists", func(datum *extended.Extended) { datum.DurationExpected = pointer.FromInt(86400000) - datum.ExtendedExpected = pointer.FromFloat64(100.0) + datum.ExtendedExpected = pointer.FromFloat64(extended.ExtendedMaximum) }, ), Entry("multiple errors", @@ -489,14 +489,14 @@ var _ = Describe("Extended", func() { datum.Duration = nil datum.DurationExpected = pointer.FromInt(86400001) datum.Extended = nil - datum.ExtendedExpected = pointer.FromFloat64(100.1) + datum.ExtendedExpected = pointer.FromFloat64(250.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidType", "bolus"), "/type", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidSubType", "square"), "/subType", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/expectedDuration", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0, 100), "/expectedExtended", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0, extended.ExtendedMaximum), "/expectedExtended", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), ), ) }) diff --git a/data/types/bolus/normal/normal.go b/data/types/bolus/normal/normal.go index 5b939493ba..f2d9775aaf 100644 --- a/data/types/bolus/normal/normal.go +++ b/data/types/bolus/normal/normal.go @@ -9,7 +9,7 @@ import ( const ( SubType = "normal" // TODO: Rename Type to "bolus/normal"; remove SubType - NormalMaximum = 100.0 + NormalMaximum = 250.0 NormalMinimum = 0.0 ) diff --git a/data/types/bolus/normal/normal_test.go b/data/types/bolus/normal/normal_test.go index 68b73ac8a0..b73817050e 100644 --- a/data/types/bolus/normal/normal_test.go +++ b/data/types/bolus/normal/normal_test.go @@ -28,7 +28,7 @@ var _ = Describe("Normal", func() { }) It("NormalMaximum is expected", func() { - Expect(normal.NormalMaximum).To(Equal(100.0)) + Expect(normal.NormalMaximum).To(Equal(250.0)) }) It("NormalMinimum is expected", func() { @@ -96,7 +96,7 @@ var _ = Describe("Normal", func() { datum.NormalExpected = pointer.FromFloat64(-0.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, normal.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal missing; normal expected in range (lower)", func(datum *normal.Normal) { @@ -108,54 +108,54 @@ var _ = Describe("Normal", func() { Entry("normal missing; normal expected in range (upper)", func(datum *normal.Normal) { datum.Normal = nil - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.NormalExpected = pointer.FromFloat64(normal.NormalMaximum) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), ), Entry("normal missing; normal expected out of range (upper)", func(datum *normal.Normal) { datum.Normal = nil - datum.NormalExpected = pointer.FromFloat64(100.1) + datum.NormalExpected = pointer.FromFloat64(250.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal out of range (lower); normal expected missing", func(datum *normal.Normal) { datum.Normal = pointer.FromFloat64(-0.1) datum.NormalExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), ), Entry("normal out of range (lower); normal expected out of range (lower)", func(datum *normal.Normal) { datum.Normal = pointer.FromFloat64(-0.1) datum.NormalExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, normal.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal out of range (lower); normal expected in range (lower)", func(datum *normal.Normal) { datum.Normal = pointer.FromFloat64(-0.1) datum.NormalExpected = pointer.FromFloat64(0.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), ), Entry("normal out of range (lower); normal expected in range (upper)", func(datum *normal.Normal) { datum.Normal = pointer.FromFloat64(-0.1) - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.NormalExpected = pointer.FromFloat64(normal.NormalMaximum) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), ), Entry("normal out of range (lower); normal expected out of range (upper)", func(datum *normal.Normal) { datum.Normal = pointer.FromFloat64(-0.1) - datum.NormalExpected = pointer.FromFloat64(100.1) + datum.NormalExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal in range (lower); normal expected missing", func(datum *normal.Normal) { @@ -169,7 +169,7 @@ var _ = Describe("Normal", func() { datum.Normal = pointer.FromFloat64(0.0) datum.NormalExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, normal.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal in range (lower); normal expected in range (lower)", func(datum *normal.Normal) { @@ -180,96 +180,96 @@ var _ = Describe("Normal", func() { Entry("normal in range (lower); normal expected in range (upper)", func(datum *normal.Normal) { datum.Normal = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.NormalExpected = pointer.FromFloat64(normal.NormalMaximum) }, ), Entry("normal in range (lower); normal expected out of range (upper)", func(datum *normal.Normal) { datum.Normal = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(100.1) + datum.NormalExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal in range (upper); normal expected missing", func(datum *normal.Normal) { - datum.Normal = pointer.FromFloat64(100.0) + datum.Normal = pointer.FromFloat64(normal.NormalMaximum) datum.NormalExpected = nil }, ), Entry("normal in range (upper); normal expected out of range (lower)", func(datum *normal.Normal) { - datum.Normal = pointer.FromFloat64(100.0) - datum.NormalExpected = pointer.FromFloat64(99.9) + datum.Normal = pointer.FromFloat64(normal.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(249.9) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(99.9, 100.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(249.9, normal.NormalMaximum, normal.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal in range (upper); normal expected in range (lower)", func(datum *normal.Normal) { - datum.Normal = pointer.FromFloat64(100.0) - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.Normal = pointer.FromFloat64(normal.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(normal.NormalMaximum) }, ), Entry("normal in range (upper); normal expected in range (upper)", func(datum *normal.Normal) { - datum.Normal = pointer.FromFloat64(100.0) - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.Normal = pointer.FromFloat64(normal.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(normal.NormalMaximum) }, ), Entry("normal in range (upper); normal expected out of range (upper)", func(datum *normal.Normal) { - datum.Normal = pointer.FromFloat64(100.0) - datum.NormalExpected = pointer.FromFloat64(100.1) + datum.Normal = pointer.FromFloat64(normal.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 100.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, normal.NormalMaximum, normal.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal out of range (upper); normal expected missing", func(datum *normal.Normal) { - datum.Normal = pointer.FromFloat64(100.1) + datum.Normal = pointer.FromFloat64(250.1) datum.NormalExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), ), Entry("normal out of range (upper); normal expected out of range (lower)", func(datum *normal.Normal) { - datum.Normal = pointer.FromFloat64(100.1) + datum.Normal = pointer.FromFloat64(250.1) datum.NormalExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, normal.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal out of range (upper); normal expected in range (lower)", func(datum *normal.Normal) { - datum.Normal = pointer.FromFloat64(100.1) + datum.Normal = pointer.FromFloat64(250.1) datum.NormalExpected = pointer.FromFloat64(0.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), ), Entry("normal out of range (upper); normal expected in range (upper)", func(datum *normal.Normal) { - datum.Normal = pointer.FromFloat64(100.1) - datum.NormalExpected = pointer.FromFloat64(100.0) + datum.Normal = pointer.FromFloat64(250.1) + datum.NormalExpected = pointer.FromFloat64(normal.NormalMaximum) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), ), Entry("normal out of range (upper); normal expected out of range (upper)", func(datum *normal.Normal) { - datum.Normal = pointer.FromFloat64(100.1) - datum.NormalExpected = pointer.FromFloat64(100.1) + datum.Normal = pointer.FromFloat64(250.1) + datum.NormalExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("multiple errors", func(datum *normal.Normal) { datum.Type = "invalidType" datum.SubType = "invalidSubType" datum.Normal = nil - datum.NormalExpected = pointer.FromFloat64(100.1) + datum.NormalExpected = pointer.FromFloat64(250.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidType", "bolus"), "/type", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidSubType", "normal"), "/subType", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/expectedNormal", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/expectedNormal", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), ), ) }) diff --git a/data/types/calculator/calculator_test.go b/data/types/calculator/calculator_test.go index 111011cb75..54b37bbba5 100644 --- a/data/types/calculator/calculator_test.go +++ b/data/types/calculator/calculator_test.go @@ -403,7 +403,7 @@ var _ = Describe("Calculator", func() { func(datum *calculator.Calculator, units *string) { datum.Recommended.Carbohydrate = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/recommended/carb", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, calculator.InsulinCarbohydrateRatioMaximum), "/recommended/carb", NewMeta()), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/units", NewMeta()), ), Entry("units missing; recommended valid", @@ -604,7 +604,7 @@ var _ = Describe("Calculator", func() { func(datum *calculator.Calculator, units *string) { datum.Recommended.Carbohydrate = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/recommended/carb", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, calculator.InsulinCarbohydrateRatioMaximum), "/recommended/carb", NewMeta()), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"mmol/L", "mmol/l", "mg/dL", "mg/dl"}), "/units", NewMeta()), ), Entry("units invalid; recommended valid", @@ -774,7 +774,7 @@ var _ = Describe("Calculator", func() { func(datum *calculator.Calculator, units *string) { datum.Recommended.Carbohydrate = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/recommended/carb", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, calculator.InsulinCarbohydrateRatioMaximum), "/recommended/carb", NewMeta()), ), Entry("units mmol/L; recommended valid", pointer.FromString("mmol/L"), @@ -942,7 +942,7 @@ var _ = Describe("Calculator", func() { func(datum *calculator.Calculator, units *string) { datum.Recommended.Carbohydrate = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/recommended/carb", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, calculator.InsulinCarbohydrateRatioMaximum), "/recommended/carb", NewMeta()), ), Entry("units mmol/l; recommended valid", pointer.FromString("mmol/l"), @@ -1114,7 +1114,7 @@ var _ = Describe("Calculator", func() { func(datum *calculator.Calculator, units *string) { datum.Recommended.Carbohydrate = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/recommended/carb", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, calculator.InsulinCarbohydrateRatioMaximum), "/recommended/carb", NewMeta()), ), Entry("units mg/dL; recommended valid", pointer.FromString("mg/dL"), @@ -1286,7 +1286,7 @@ var _ = Describe("Calculator", func() { func(datum *calculator.Calculator, units *string) { datum.Recommended.Carbohydrate = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/recommended/carb", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, calculator.InsulinCarbohydrateRatioMaximum), "/recommended/carb", NewMeta()), ), Entry("units mg/dl; recommended valid", pointer.FromString("mg/dl"), diff --git a/data/types/calculator/recommended.go b/data/types/calculator/recommended.go index 69168e7801..64908c00be 100644 --- a/data/types/calculator/recommended.go +++ b/data/types/calculator/recommended.go @@ -6,12 +6,12 @@ import ( ) const ( - CarbohydrateMaximum = 100.0 + CarbohydrateMaximum = 250.0 CarbohydrateMinimum = 0.0 - CorrectionMaximum = 100.0 - CorrectionMinimum = -100.0 - NetMaximum = 100.0 - NetMinimum = -100.0 + CorrectionMaximum = 250.0 + CorrectionMinimum = -250.0 + NetMaximum = 250.0 + NetMinimum = -250.0 ) type Recommended struct { diff --git a/data/types/calculator/recommended_test.go b/data/types/calculator/recommended_test.go index ebbc12c20c..17eced5646 100644 --- a/data/types/calculator/recommended_test.go +++ b/data/types/calculator/recommended_test.go @@ -35,7 +35,7 @@ func CloneRecommended(datum *calculator.Recommended) *calculator.Recommended { var _ = Describe("Recommended", func() { It("CarbohydrateMaximum is expected", func() { - Expect(calculator.CarbohydrateMaximum).To(Equal(100.0)) + Expect(calculator.CarbohydrateMaximum).To(Equal(250.0)) }) It("CarbohydrateMinimum is expected", func() { @@ -43,19 +43,19 @@ var _ = Describe("Recommended", func() { }) It("CorrectionMaximum is expected", func() { - Expect(calculator.CorrectionMaximum).To(Equal(100.0)) + Expect(calculator.CorrectionMaximum).To(Equal(250.0)) }) It("CorrectionMinimum is expected", func() { - Expect(calculator.CorrectionMinimum).To(Equal(-100.0)) + Expect(calculator.CorrectionMinimum).To(Equal(-250.0)) }) It("NetMaximum is expected", func() { - Expect(calculator.NetMaximum).To(Equal(100.0)) + Expect(calculator.NetMaximum).To(Equal(250.0)) }) It("NetMinimum is expected", func() { - Expect(calculator.NetMinimum).To(Equal(-100.0)) + Expect(calculator.NetMinimum).To(Equal(-250.0)) }) Context("ParseRecommended", func() { @@ -88,7 +88,7 @@ var _ = Describe("Recommended", func() { ), Entry("carbohydrate out of range (lower)", func(datum *calculator.Recommended) { datum.Carbohydrate = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-0.1, 0, 100), "/carb"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-0.1, 0, calculator.InsulinCarbohydrateRatioMaximum), "/carb"), ), Entry("carbohydrate in range (lower)", func(datum *calculator.Recommended) { datum.Carbohydrate = pointer.FromFloat64(0.0) }, @@ -97,15 +97,15 @@ var _ = Describe("Recommended", func() { func(datum *calculator.Recommended) { datum.Carbohydrate = pointer.FromFloat64(100.0) }, ), Entry("carbohydrate out of range (upper)", - func(datum *calculator.Recommended) { datum.Carbohydrate = pointer.FromFloat64(100.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(100.1, 0, 100), "/carb"), + func(datum *calculator.Recommended) { datum.Carbohydrate = pointer.FromFloat64(250.1) }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(250.1, 0, calculator.InsulinCarbohydrateRatioMaximum), "/carb"), ), Entry("correction missing", func(datum *calculator.Recommended) { datum.Correction = nil }, ), Entry("correction out of range (lower)", - func(datum *calculator.Recommended) { datum.Correction = pointer.FromFloat64(-100.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-100.1, -100, 100), "/correction"), + func(datum *calculator.Recommended) { datum.Correction = pointer.FromFloat64(-250.1) }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-250.1, calculator.CorrectionMinimum, calculator.CorrectionMaximum), "/correction"), ), Entry("correction in range (lower)", func(datum *calculator.Recommended) { datum.Correction = pointer.FromFloat64(-100.0) }, @@ -114,15 +114,15 @@ var _ = Describe("Recommended", func() { func(datum *calculator.Recommended) { datum.Correction = pointer.FromFloat64(100.0) }, ), Entry("correction out of range (upper)", - func(datum *calculator.Recommended) { datum.Correction = pointer.FromFloat64(100.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(100.1, -100, 100), "/correction"), + func(datum *calculator.Recommended) { datum.Correction = pointer.FromFloat64(250.1) }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(250.1, calculator.CorrectionMinimum, calculator.CorrectionMaximum), "/correction"), ), Entry("net missing", func(datum *calculator.Recommended) { datum.Net = nil }, ), Entry("net out of range (lower)", - func(datum *calculator.Recommended) { datum.Net = pointer.FromFloat64(-100.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-100.1, -100, 100), "/net"), + func(datum *calculator.Recommended) { datum.Net = pointer.FromFloat64(-250.1) }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-250.1, calculator.NetMinimum, calculator.NetMaximum), "/net"), ), Entry("net in range (lower)", func(datum *calculator.Recommended) { datum.Net = pointer.FromFloat64(-100.0) }, @@ -131,18 +131,18 @@ var _ = Describe("Recommended", func() { func(datum *calculator.Recommended) { datum.Net = pointer.FromFloat64(100.0) }, ), Entry("net out of range (upper)", - func(datum *calculator.Recommended) { datum.Net = pointer.FromFloat64(100.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(100.1, -100, 100), "/net"), + func(datum *calculator.Recommended) { datum.Net = pointer.FromFloat64(250.1) }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(250.1, calculator.NetMinimum, calculator.NetMaximum), "/net"), ), Entry("multiple errors", func(datum *calculator.Recommended) { datum.Carbohydrate = pointer.FromFloat64(-0.1) - datum.Correction = pointer.FromFloat64(-100.1) - datum.Net = pointer.FromFloat64(-100.1) + datum.Correction = pointer.FromFloat64(-250.1) + datum.Net = pointer.FromFloat64(-250.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-0.1, 0, 100), "/carb"), - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-100.1, -100, 100), "/correction"), - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-100.1, -100, 100), "/net"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-0.1, 0, calculator.InsulinCarbohydrateRatioMaximum), "/carb"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-250.1, calculator.CorrectionMinimum, calculator.CorrectionMaximum), "/correction"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-250.1, calculator.NetMinimum, calculator.NetMaximum), "/net"), ), ) }) diff --git a/data/types/settings/pump/bolus_amount_maximum.go b/data/types/settings/pump/bolus_amount_maximum.go index 97e1ea5ba0..3549b52f50 100644 --- a/data/types/settings/pump/bolus_amount_maximum.go +++ b/data/types/settings/pump/bolus_amount_maximum.go @@ -9,7 +9,7 @@ import ( const ( BolusAmountMaximumUnitsUnits = "Units" - BolusAmountMaximumValueUnitsMaximum = 100.0 + BolusAmountMaximumValueUnitsMaximum = 250.0 BolusAmountMaximumValueUnitsMinimum = 0.0 ) diff --git a/data/types/settings/pump/bolus_amount_maximum_test.go b/data/types/settings/pump/bolus_amount_maximum_test.go index 16ceb96b92..efb4e3f503 100644 --- a/data/types/settings/pump/bolus_amount_maximum_test.go +++ b/data/types/settings/pump/bolus_amount_maximum_test.go @@ -23,7 +23,7 @@ var _ = Describe("BolusAmountMaximum", func() { }) It("BolusAmountMaximumValueUnitsMaximum is expected", func() { - Expect(pump.BolusAmountMaximumValueUnitsMaximum).To(Equal(100.0)) + Expect(pump.BolusAmountMaximumValueUnitsMaximum).To(Equal(250.0)) }) It("BolusAmountMaximumValueUnitsMinimum is expected", func() { @@ -98,14 +98,14 @@ var _ = Describe("BolusAmountMaximum", func() { Entry("units missing; value in range (upper)", func(datum *pump.BolusAmountMaximum) { datum.Units = nil - datum.Value = pointer.FromFloat64(100.0) + datum.Value = pointer.FromFloat64(pump.BolusAmountMaximumValueUnitsMaximum) }, errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/units"), ), Entry("units missing; value out of range (upper)", func(datum *pump.BolusAmountMaximum) { datum.Units = nil - datum.Value = pointer.FromFloat64(100.1) + datum.Value = pointer.FromFloat64(250.1) }, errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/units"), ), @@ -134,14 +134,14 @@ var _ = Describe("BolusAmountMaximum", func() { Entry("units invalid; value in range (upper)", func(datum *pump.BolusAmountMaximum) { datum.Units = pointer.FromString("invalid") - datum.Value = pointer.FromFloat64(100.0) + datum.Value = pointer.FromFloat64(pump.BolusAmountMaximumValueUnitsMaximum) }, errorsTest.WithPointerSource(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"Units"}), "/units"), ), Entry("units invalid; value out of range (upper)", func(datum *pump.BolusAmountMaximum) { datum.Units = pointer.FromString("invalid") - datum.Value = pointer.FromFloat64(100.1) + datum.Value = pointer.FromFloat64(250.1) }, errorsTest.WithPointerSource(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"Units"}), "/units"), ), @@ -157,7 +157,7 @@ var _ = Describe("BolusAmountMaximum", func() { datum.Units = pointer.FromString("Units") datum.Value = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 100.0), "/value"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-0.1, 0.0, pump.BolusAmountMaximumValueUnitsMaximum), "/value"), ), Entry("units Units; value in range (lower)", func(datum *pump.BolusAmountMaximum) { @@ -168,15 +168,15 @@ var _ = Describe("BolusAmountMaximum", func() { Entry("units Units; value in range (upper)", func(datum *pump.BolusAmountMaximum) { datum.Units = pointer.FromString("Units") - datum.Value = pointer.FromFloat64(100.0) + datum.Value = pointer.FromFloat64(pump.BolusAmountMaximumValueUnitsMaximum) }, ), Entry("units Units; value out of range (upper)", func(datum *pump.BolusAmountMaximum) { datum.Units = pointer.FromString("Units") - datum.Value = pointer.FromFloat64(100.1) + datum.Value = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(100.1, 0.0, 100.0), "/value"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(250.1, 0.0, pump.BolusAmountMaximumValueUnitsMaximum), "/value"), ), Entry("multiple errors", func(datum *pump.BolusAmountMaximum) { @@ -233,7 +233,7 @@ var _ = Describe("BolusAmountMaximum", func() { It("returns expected range for units Units", func() { minimum, maximum := pump.BolusAmountMaximumValueRangeForUnits(pointer.FromString("Units")) Expect(minimum).To(Equal(0.0)) - Expect(maximum).To(Equal(100.0)) + Expect(maximum).To(Equal(pump.BolusAmountMaximumValueUnitsMaximum)) }) }) }) From 3a32367935bee75e477ac63d5fe4b0885c0dcc7a Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 9 Aug 2024 12:25:54 +1200 Subject: [PATCH 389/413] expand device model list --- data/deduplicator/deduplicator/device_deactivate_hash.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index 0419e8a827..748befdbcb 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -33,11 +33,11 @@ var DeviceDeactivateLegacyHashManufacturerDeviceModels = map[string][]string{ "Bayer": {"Contour Next Link", "Contour Next Link 2.4", "Contour Next", "Contour USB", "Contour Next USB", "Contour Next One", "Contour", "Contour Next EZ", "Contour Plus", "Contour Plus Blue"}, "Dexcom": {"G5 touchscreen receiver", "G6 touchscreen receiver"}, "GlucoRx": {"Nexus", "HCT", "Nexus Mini Ultra", "Go"}, - "Insulet": {"Dash", "Eros"}, + "Insulet": {"Dash", "Eros", "OmniPod"}, "i-SENS": {"CareSens"}, "MicroTech": {"Equil"}, "Roche": {"Aviva Connect", "Performa Connect", "Guide", "Instant (single-button)", "Guide Me", "Instant (two-button)", "Instant S (single-button)", "ReliOn Platinum"}, - "Tandem": {"1002717"}, + "Tandem": {"1002717", "5602", "5448004", "5448003", "5448001", "5448", "4628003", "4628", "10037177", "1001357", "1000354", "1000096"}, } type DeviceDeactivateHash struct { From 4ede27e1ee1da120cfc72d0126bb02397a18b5e7 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 13 Aug 2024 10:29:33 +1200 Subject: [PATCH 390/413] helper script updates --- .../verify/cleanup_user_data.sh | 6 +++-- .../verify/fetch_blobs.sh | 6 +++-- .../verify/process_all_blobs.sh | 25 ++++++++++++++----- .../verify/upload_blob.sh | 10 ++++++-- 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh b/migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh index 0f66d4d49e..ec4bd6c914 100644 --- a/migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh +++ b/migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh @@ -10,12 +10,14 @@ check_val() { fi } -check_val $SERVER_SECRET "SERVER_SECRET" +SECRET=$(op item get "qa3 server secret" --account tidepool.1password.com --fields label=credential --format json | jq -r '.value') + +check_val $SECRET "SECRET" check_val $USER_ID_ONE "USER_ID_ONE" if [[ -z "$SERVER_TOKEN" ]]; then - SERVER_TOKEN="$(curl -s -I -X POST -H "X-Tidepool-Server-Secret: $SERVER_SECRET" -H "X-Tidepool-Server-Name: devops" "https://${API_ENV}.tidepool.org/auth/serverlogin" | grep 'x-tidepool-session-token' | sed 's/[^:]*: //')" + SERVER_TOKEN="$(curl -s -I -X POST -H "X-Tidepool-Server-Secret: $SECRET" -H "X-Tidepool-Server-Name: devops" "https://${API_ENV}.tidepool.org/auth/serverlogin" | grep 'x-tidepool-session-token' | sed 's/[^:]*: //')" fi check_val $SERVER_TOKEN "SERVER_TOKEN" diff --git a/migrations/20231128_jellyfish_migration/verify/fetch_blobs.sh b/migrations/20231128_jellyfish_migration/verify/fetch_blobs.sh index 3a613cc733..88e8406bb0 100644 --- a/migrations/20231128_jellyfish_migration/verify/fetch_blobs.sh +++ b/migrations/20231128_jellyfish_migration/verify/fetch_blobs.sh @@ -10,11 +10,13 @@ check_val() { fi } +SECRET=$(op item get "qa3 server secret" --account tidepool.1password.com --fields label=credential --format json | jq -r '.value') + check_val $JSON_FILE "JSON_FILE" check_val $OUTPUT_DIR "OUTPUT_DIR" -check_val $SERVER_SECRET "SERVER_SECRET" +check_val $SECRET "SECRET" -SESSION_TOKEN="$(curl -s -I -X POST -H "X-Tidepool-Server-Secret: $SERVER_SECRET" -H "X-Tidepool-Server-Name: devops" "https://${API_ENV}.tidepool.org/auth/serverlogin" | grep 'x-tidepool-session-token' | sed 's/[^:]*: //')" +SESSION_TOKEN="$(curl -s -I -X POST -H "X-Tidepool-Server-Secret: $SECRET" -H "X-Tidepool-Server-Name: devops" "https://${API_ENV}.tidepool.org/auth/serverlogin" | grep 'x-tidepool-session-token' | sed 's/[^:]*: //')" jq -c '.[]' $JSON_FILE | while read i; do diff --git a/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh b/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh index 9c5428d5da..d6a68f84e6 100644 --- a/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh +++ b/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh @@ -1,13 +1,26 @@ #!/bin/bash -BLOBS_DIR=~/Documents/tmp/blob_files/tandemCIQ100035490810069 +BLOBS_DIR=~/Documents/tmp/blob_files/InsOmn +UPLOADED=blob_uploads.log +FAIL_UPLOAD=blob_errors.log USER_ID=6a452338-5064-4795-81ca-84957bad2280 USER_EMAIL=$1 USER_PW=$2 -SERVER_TOKEN="$(curl -s -I -X POST -H "X-Tidepool-Server-Secret: $SERVER_SECRET" -H "X-Tidepool-Server-Name: devops" "https://${API_ENV}.tidepool.org/auth/serverlogin" | grep 'x-tidepool-session-token' | sed 's/[^:]*: //')" +for filename in $BLOBS_DIR*/**/*blob*.gz; do + + if grep -wq "$filename" $UPLOADED; then + echo "$filename already uploaded" + else + if grep -wq "$filename" $FAIL_UPLOAD; then + echo "$filename already failed to upload" + else + + SECRET=$(op item get "qa3 server secret" --account tidepool.1password.com --fields label=credential --format json | jq -r '.value') + SERVER_TOKEN="$(curl -s -I -X POST -H "X-Tidepool-Server-Secret: $SECRET" -H "X-Tidepool-Server-Name: devops" "https://${API_ENV}.tidepool.org/auth/serverlogin" | grep 'x-tidepool-session-token' | sed 's/[^:]*: //')" + + source ./upload_blob.sh "$filename" "$USER_EMAIL" "$USER_PW" + source ./cleanup_user_data.sh "$USER_ID" "$SERVER_TOKEN" + fi + fi -for filename in $BLOBS_DIR/**/*blob.gz; do - echo "$filename" - source ./upload_blob.sh "$filename" "$USER_EMAIL" "$USER_PW" - source ./cleanup_user_data.sh "$USER_ID" "$SERVER_TOKEN" done diff --git a/migrations/20231128_jellyfish_migration/verify/upload_blob.sh b/migrations/20231128_jellyfish_migration/verify/upload_blob.sh index 399f5562d3..27c2a59aea 100644 --- a/migrations/20231128_jellyfish_migration/verify/upload_blob.sh +++ b/migrations/20231128_jellyfish_migration/verify/upload_blob.sh @@ -50,7 +50,13 @@ if [ "$SUCCESS" = true ]; then echo "$records" else echo 'upload failed!' - error_details=$(echo "$output" | grep -A100000 'platform add data to dataset failed.' | grep -B100000 'upload.toPlatform: failed') + error_details=$(echo "$output" | grep -A100000 'error' | grep -B100000 '') + + if [[ -z "$error_details" ]]; then + error_details=$(echo "$output" | grep -A100000 'platform add data to dataset failed.' | grep -B100000 'upload.toPlatform: failed') + fi + + echo "{'blob':'$BLOB_FILE', 'details':'{$error_details}'}" >>blob_errors.log - echo "$error_details" + echo "$output" fi From 390fce1fe8b503182e4fb299b2cb5c0d316a3713 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 21 Aug 2024 09:27:39 +1200 Subject: [PATCH 391/413] naming --- .../deduplicator/device_deactivate_hash.go | 11 ++++++----- data/deduplicator/deduplicator/hash.go | 8 ++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index 748befdbcb..7eb7f71bfd 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -33,11 +33,12 @@ var DeviceDeactivateLegacyHashManufacturerDeviceModels = map[string][]string{ "Bayer": {"Contour Next Link", "Contour Next Link 2.4", "Contour Next", "Contour USB", "Contour Next USB", "Contour Next One", "Contour", "Contour Next EZ", "Contour Plus", "Contour Plus Blue"}, "Dexcom": {"G5 touchscreen receiver", "G6 touchscreen receiver"}, "GlucoRx": {"Nexus", "HCT", "Nexus Mini Ultra", "Go"}, - "Insulet": {"Dash", "Eros", "OmniPod"}, "i-SENS": {"CareSens"}, "MicroTech": {"Equil"}, "Roche": {"Aviva Connect", "Performa Connect", "Guide", "Instant (single-button)", "Guide Me", "Instant (two-button)", "Instant S (single-button)", "ReliOn Platinum"}, - "Tandem": {"1002717", "5602", "5448004", "5448003", "5448001", "5448", "4628003", "4628", "10037177", "1001357", "1000354", "1000096"}, + + "Insulet": {"Dash", "Eros", "OmniPod"}, + "Tandem": {"1002717", "5602", "5448004", "5448003", "5448001", "5448", "4628003", "4628", "10037177", "1001357", "1000354", "1000096"}, } type DeviceDeactivateHash struct { @@ -147,7 +148,7 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore return errors.New("data set data is missing") } - opts := NewDefaultDeviceDeactivateHashOptions() + options := NewDefaultDeviceDeactivateHashOptions() if getDeviceDeactivateHashVersion(dataSet) == DeviceDeactivateHashVersionLegacy { filter := &data.DataSetFilter{IsLegacy: pointer.FromBool(true), DeviceID: dataSet.DeviceID} @@ -159,12 +160,12 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore } if len(uploads) != 0 { if uploads[0].LegacyGroupID != nil { - opts = NewLegacyDeviceDeactivateHashOptions(*uploads[0].LegacyGroupID) + options = NewLegacyDeviceDeactivateHashOptions(*uploads[0].LegacyGroupID) } } } - if err := AssignDataSetDataIdentityHashes(dataSetData, opts); err != nil { + if err := AssignDataSetDataIdentityHashes(dataSetData, options); err != nil { return err } return d.Base.AddData(ctx, repository, dataSet, dataSetData) diff --git a/data/deduplicator/deduplicator/hash.go b/data/deduplicator/deduplicator/hash.go index 7c8103c98e..5b70c0d2b8 100644 --- a/data/deduplicator/deduplicator/hash.go +++ b/data/deduplicator/deduplicator/hash.go @@ -40,11 +40,11 @@ func (d deviceDeactivateHashOptions) ValidateLegacy() error { return nil } -func AssignDataSetDataIdentityHashes(dataSetData data.Data, opts deviceDeactivateHashOptions) error { +func AssignDataSetDataIdentityHashes(dataSetData data.Data, options deviceDeactivateHashOptions) error { for _, dataSetDatum := range dataSetData { var hash string - if opts.version == DeviceDeactivateHashVersionLegacy { - if err := opts.ValidateLegacy(); err != nil { + if options.version == DeviceDeactivateHashVersionLegacy { + if err := options.ValidateLegacy(); err != nil { return err } fields, err := dataSetDatum.LegacyIdentityFields() @@ -56,7 +56,7 @@ func AssignDataSetDataIdentityHashes(dataSetData data.Data, opts deviceDeactivat if err != nil { return errors.Wrapf(err, "unable to generate legacy identity hash for datum %T", dataSetDatum) } - hash, err = GenerateLegacyIdentityHash([]string{hash, *opts.legacyGroupID}) + hash, err = GenerateLegacyIdentityHash([]string{hash, *options.legacyGroupID}) if err != nil { return errors.Wrapf(err, "unable to generate legacy identity hash with legacy groupID for datum %T", dataSetDatum) } From 8d2c0ff5ff903b10118810eebbced18138b88980 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 21 Aug 2024 09:28:42 +1200 Subject: [PATCH 392/413] script updates from testing --- .../verify/cleanup_user_data.sh | 1 - .../verify/fetch_blobs.sh | 76 ++++++++++++------- .../verify/process_all_blobs.sh | 28 +++---- .../verify/upload_blob.sh | 24 ++++-- 4 files changed, 81 insertions(+), 48 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh b/migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh index ec4bd6c914..7d22ef8499 100644 --- a/migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh +++ b/migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh @@ -16,7 +16,6 @@ check_val $SECRET "SECRET" check_val $USER_ID_ONE "USER_ID_ONE" if [[ -z "$SERVER_TOKEN" ]]; then - SERVER_TOKEN="$(curl -s -I -X POST -H "X-Tidepool-Server-Secret: $SECRET" -H "X-Tidepool-Server-Name: devops" "https://${API_ENV}.tidepool.org/auth/serverlogin" | grep 'x-tidepool-session-token' | sed 's/[^:]*: //')" fi diff --git a/migrations/20231128_jellyfish_migration/verify/fetch_blobs.sh b/migrations/20231128_jellyfish_migration/verify/fetch_blobs.sh index 88e8406bb0..6d1ee37f99 100644 --- a/migrations/20231128_jellyfish_migration/verify/fetch_blobs.sh +++ b/migrations/20231128_jellyfish_migration/verify/fetch_blobs.sh @@ -1,7 +1,7 @@ #!/bin/bash -API_ENV=qa2.development JSON_FILE=$1 OUTPUT_DIR=$2 +LOG_PREFIX=prod_blob check_val() { if [[ -z "$1" ]]; then @@ -10,7 +10,13 @@ check_val() { fi } -SECRET=$(op item get "qa3 server secret" --account tidepool.1password.com --fields label=credential --format json | jq -r '.value') +## PRD +SECRET=$(op item get "PRD Server Secret" --account tidepool.1password.com --fields label=credential --format json | jq -r '.value') +API_ENV=api + +## QA +# SECRET=$(op item get "qa3 server secret" --account tidepool.1password.com --fields label=credential --format json | jq -r '.value') +# API_ENV=qa2.development check_val $JSON_FILE "JSON_FILE" check_val $OUTPUT_DIR "OUTPUT_DIR" @@ -18,40 +24,58 @@ check_val $SECRET "SECRET" SESSION_TOKEN="$(curl -s -I -X POST -H "X-Tidepool-Server-Secret: $SECRET" -H "X-Tidepool-Server-Name: devops" "https://${API_ENV}.tidepool.org/auth/serverlogin" | grep 'x-tidepool-session-token' | sed 's/[^:]*: //')" -jq -c '.[]' $JSON_FILE | while read i; do +check_val $SESSION_TOKEN "SESSION_TOKEN" - DEVICE_ID=$(jq -r '.deviceId' <<<"$i") - check_val $DEVICE_ID "DEVICE_ID" - BLOB_ID=$(jq -r '.blobId' <<<"$i") - check_val $BLOB_ID "BLOB_ID" +## enbale downloading o +counter=0 +jq -c '.[]' $JSON_FILE | while read i; do - if [[ "$DEVICE_ID" =~ .*"tandem".* ]]; then - OUTPUT_FILE="$OUTPUT_DIR/$DEVICE_ID/$BLOB_ID"_blob.gz - else - OUTPUT_FILE="$OUTPUT_DIR/$DEVICE_ID/$BLOB_ID"_blob.ibf - fi + counter=$((counter+1)) - mkdir -p "$OUTPUT_DIR/$DEVICE_ID" + if [[ "$counter" == 12 ]]; then + # reset counter + counter=0 - check_val $OUTPUT_FILE "OUTPUT_FILE" + DEVICE_ID=$(jq -r '.deviceId' <<<"$i") + check_val $DEVICE_ID "DEVICE_ID" - http_response=$(curl -s -o $OUTPUT_FILE -w "%{response_code}" --request GET \ - --url https://${API_ENV}.tidepool.org/v1/blobs/${BLOB_ID}/content \ - --header 'Accept: */*' \ - --header "X-Tidepool-Session-Token: $SESSION_TOKEN") + BLOB_ID=$(jq -r '.blobId' <<<"$i") + check_val $BLOB_ID "BLOB_ID" - if [ $http_response != "200" ]; then - echo "$http_response error downloading blob $BLOB_ID for device $DEVICE_ID" - rm -rf $OUTPUT_FILE - else if [[ "$DEVICE_ID" =~ .*"tandem".* ]]; then - echo "status $http_response done downloading tandem blob $OUTPUT_FILE" + OUTPUT_FILE="$OUTPUT_DIR/$DEVICE_ID/$BLOB_ID"_blob.gz else - gzip $OUTPUT_FILE - echo "status $http_response done downloading omnipod blob $OUTPUT_FILE" + OUTPUT_FILE="$OUTPUT_DIR/$DEVICE_ID/$BLOB_ID"_blob.ibf fi - fi + # is already downloaded? + if grep -wq "$OUTPUT_FILE" "${LOG_PREFIX}_upload.log" || grep -wq "$OUTPUT_FILE" "${LOG_PREFIX}_error.log"; then + echo "$OUTPUT_FILE already downloaded" + else + + mkdir -p "$OUTPUT_DIR/$DEVICE_ID" + + check_val $OUTPUT_FILE "OUTPUT_FILE" + + + http_response=$(curl -s -o $OUTPUT_FILE -w "%{response_code}" --request GET \ + --url https://${API_ENV}.tidepool.org/v1/blobs/${BLOB_ID}/content \ + --header 'Accept: */*' \ + --header "X-Tidepool-Session-Token: $SESSION_TOKEN") + + if [ $http_response != "200" ]; then + echo "$http_response error downloading blob $BLOB_ID for device $DEVICE_ID" + rm -rf $OUTPUT_FILE + else + if [[ "$DEVICE_ID" =~ .*"tandem".* ]]; then + echo "status $http_response done downloading tandem blob $OUTPUT_FILE" + else + gzip $OUTPUT_FILE + echo "status $http_response done downloading omnipod blob $OUTPUT_FILE" + fi + fi + fi + fi done diff --git a/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh b/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh index d6a68f84e6..02235e79a6 100644 --- a/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh +++ b/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh @@ -1,26 +1,26 @@ #!/bin/bash -BLOBS_DIR=~/Documents/tmp/blob_files/InsOmn -UPLOADED=blob_uploads.log -FAIL_UPLOAD=blob_errors.log +BLOBS_DIR=~/Documents/tmp/prd_blobs/tandem USER_ID=6a452338-5064-4795-81ca-84957bad2280 USER_EMAIL=$1 USER_PW=$2 +LOG_PREFIX=prod_blob for filename in $BLOBS_DIR*/**/*blob*.gz; do - if grep -wq "$filename" $UPLOADED; then - echo "$filename already uploaded" + if grep -wq "$filename" "${LOG_PREFIX}_upload.log"; then + echo "$filename already uploaded so cleaning up" + file_path=$(echo $filename | rev | cut -d"/" -f2- | rev) + rm -rf "$file_path" + echo "$file_path removed" + elif grep -wq "$filename" "${LOG_PREFIX}_error.log"; then + echo "$filename already failed to upload" else - if grep -wq "$filename" $FAIL_UPLOAD; then - echo "$filename already failed to upload" - else - SECRET=$(op item get "qa3 server secret" --account tidepool.1password.com --fields label=credential --format json | jq -r '.value') - SERVER_TOKEN="$(curl -s -I -X POST -H "X-Tidepool-Server-Secret: $SECRET" -H "X-Tidepool-Server-Name: devops" "https://${API_ENV}.tidepool.org/auth/serverlogin" | grep 'x-tidepool-session-token' | sed 's/[^:]*: //')" + SECRET=$(op item get "qa3 server secret" --account tidepool.1password.com --fields label=credential --format json | jq -r '.value') + SERVER_TOKEN="$(curl -s -I -X POST -H "X-Tidepool-Server-Secret: $SECRET" -H "X-Tidepool-Server-Name: devops" "https://${API_ENV}.tidepool.org/auth/serverlogin" | grep 'x-tidepool-session-token' | sed 's/[^:]*: //')" - source ./upload_blob.sh "$filename" "$USER_EMAIL" "$USER_PW" - source ./cleanup_user_data.sh "$USER_ID" "$SERVER_TOKEN" - fi - fi + source ./upload_blob.sh "$filename" "$USER_EMAIL" "$USER_PW" "$LOG_PREFIX" + source ./cleanup_user_data.sh "$USER_ID" "$SERVER_TOKEN" + fi done diff --git a/migrations/20231128_jellyfish_migration/verify/upload_blob.sh b/migrations/20231128_jellyfish_migration/verify/upload_blob.sh index 27c2a59aea..4f03fd0ebe 100644 --- a/migrations/20231128_jellyfish_migration/verify/upload_blob.sh +++ b/migrations/20231128_jellyfish_migration/verify/upload_blob.sh @@ -2,6 +2,7 @@ BLOB_FILE=$1 USER_EMAIL=$2 USER_PW=$3 +OUTPUT_FILE_PREFIX=$4 UPLOADER_DIR=~/Documents/src/tidepool/uploader SCRIPT=$(realpath "$0") @@ -29,9 +30,16 @@ start=$(date +%s) SUCCESS=false output='not yet run' +UPLOAD_LOG=_upload.log +ERROR_LOG=_error.log + +if [[ -n "$OUTPUT_FILE_PREFIX" ]]; then + UPLOAD_LOG="${BASE_DIR}/${OUTPUT_FILE_PREFIX}${UPLOAD_LOG}" + ERROR_LOG="${BASE_DIR}/${OUTPUT_FILE_PREFIX}${ERROR_LOG}" +fi + if [[ "$BLOB_FILE" =~ .*"tandem".* ]]; then output=$(node -r @babel/register lib/drivers/tandem/cli/loader.js loader.js -f $BLOB_FILE -u $USER_EMAIL -p $USER_PW) - echo "$output" echo "$output" | grep -q 'upload.toPlatform: all good' && SUCCESS=true else output=$(node -r @babel/register lib/drivers/insulet/cli/ibf_loader.js ibf_loader.js -f $BLOB_FILE -u $USER_EMAIL -p $USER_PW) @@ -46,17 +54,19 @@ if [ "$SUCCESS" = true ]; then echo 'upload all good' records=$(echo "$output" | grep -A100000 'attempting to upload' | grep -B100000 'device data records') runtime=$((end - start)) - echo "{'blob':'$BLOB_FILE', 'account':'$USER_EMAIL', 'time': '$runtime', 'records': '$records' }" >>blob_uploads.log + echo "{"blob":"$BLOB_FILE", "account":"$USER_EMAIL", "time": "$runtime", "records": "$records" }" >>"$UPLOAD_LOG" echo "$records" else echo 'upload failed!' - error_details=$(echo "$output" | grep -A100000 'error' | grep -B100000 '') - + + error_details=$(echo "$output" | grep -A100000 'add data to dataset failed' | grep -B100000 'Offending record for error') + if [[ -z "$error_details" ]]; then - error_details=$(echo "$output" | grep -A100000 'platform add data to dataset failed.' | grep -B100000 'upload.toPlatform: failed') + error_details=$(echo "$output" | grep -A100000 'Error' | grep -B100000 '') fi - - echo "{'blob':'$BLOB_FILE', 'details':'{$error_details}'}" >>blob_errors.log + echo "{"blob":"$BLOB_FILE", "details":{$error_details}}" >>"$ERROR_LOG" echo "$output" fi + + From f75d16c14cd414e9c12ac7b96333c7b8d3ba9103 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 2 Sep 2024 15:05:47 +1200 Subject: [PATCH 393/413] testing updates --- .../verify/cleanup_user_data.sh | 5 +- .../verify/data_verify.go | 62 ++++++++++++++++++- .../verify/fetch_blobs.sh | 14 ++--- .../verify/process_all_blobs.sh | 22 ++++--- .../verify/upload_blob.sh | 18 +++--- .../verify/verify.go | 28 +++++++++ 6 files changed, 122 insertions(+), 27 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh b/migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh index 7d22ef8499..c818a5ddeb 100644 --- a/migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh +++ b/migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh @@ -10,12 +10,11 @@ check_val() { fi } -SECRET=$(op item get "qa3 server secret" --account tidepool.1password.com --fields label=credential --format json | jq -r '.value') - -check_val $SECRET "SECRET" check_val $USER_ID_ONE "USER_ID_ONE" if [[ -z "$SERVER_TOKEN" ]]; then + SECRET=$(op item get "qa3 server secret" --account tidepool.1password.com --fields label=credential --format json | jq -r '.value') + check_val $SECRET "SECRET" SERVER_TOKEN="$(curl -s -I -X POST -H "X-Tidepool-Server-Secret: $SECRET" -H "X-Tidepool-Server-Name: devops" "https://${API_ENV}.tidepool.org/auth/serverlogin" | grep 'x-tidepool-session-token' | sed 's/[^:]*: //')" fi diff --git a/migrations/20231128_jellyfish_migration/verify/data_verify.go b/migrations/20231128_jellyfish_migration/verify/data_verify.go index cfafd27822..77e117e045 100644 --- a/migrations/20231128_jellyfish_migration/verify/data_verify.go +++ b/migrations/20231128_jellyfish_migration/verify/data_verify.go @@ -62,8 +62,6 @@ func NewDataVerify(ctx context.Context, dataC *mongo.Collection) (*DataVerify, e var DatasetTypes = []string{"cbg", "smbg", "basal", "bolus", "deviceEvent", "wizard", "pumpSettings"} -//archivedDatasetId - func (m *DataVerify) fetchDataSetNotDeduped(uploadID string, dataTypes []string) (map[string][]map[string]interface{}, error) { if m.dataC == nil { return nil, errors.New("missing data collection") @@ -104,6 +102,45 @@ func (m *DataVerify) fetchDataSetNotDeduped(uploadID string, dataTypes []string) return typeSet, nil } +func (m *DataVerify) fetchDeviceData(deviceID string, dataTypes []string) (map[string][]map[string]interface{}, error) { + if m.dataC == nil { + return nil, errors.New("missing data collection") + } + + typeSet := map[string][]map[string]interface{}{} + + for _, dType := range dataTypes { + + dset := []map[string]interface{}{} + + filter := bson.M{ + "deviceId": deviceID, + "type": dType, + } + + sort := bson.D{{Key: "time", Value: 1}} + + if dType == "deviceEvent" || dType == "bolus" { + sort = bson.D{{Key: "time", Value: 1}, {Key: "subType", Value: 1}} + } + + dDataCursor, err := m.dataC.Find(m.ctx, filter, &options.FindOptions{ + Sort: sort, + }) + if err != nil { + return nil, err + } + defer dDataCursor.Close(m.ctx) + + if err := dDataCursor.All(m.ctx, &dset); err != nil { + return nil, err + } + log.Printf("got device datasets [%s][%s][%d] results", deviceID, dType, len(dset)) + typeSet[dType] = dset + } + return typeSet, nil +} + func (m *DataVerify) fetchDataSet(uploadID string, dataTypes []string) (map[string][]map[string]interface{}, error) { if m.dataC == nil { return nil, errors.New("missing data collection") @@ -363,6 +400,27 @@ func (m *DataVerify) VerifyDeduped(uploadID string, dataTyes []string) error { return nil } +func (m *DataVerify) VerifyDeviceUploads(deviceID string, dataTyes []string) error { + + if len(dataTyes) == 0 { + dataTyes = DatasetTypes + } + datasets, err := m.fetchDeviceData(deviceID, dataTyes) + if err != nil { + return err + } + + if len(datasets) != 0 { + notDedupedPath := filepath.Join(".", "_device_data", deviceID) + for dType, dTypeItems := range datasets { + if len(dTypeItems) > 0 { + writeFileData(dTypeItems, notDedupedPath, fmt.Sprintf("%s_data.json", dType), true) + } + } + } + return nil +} + func writeFileData(data interface{}, path string, name string, asJSON bool) { if data == nil || path == "" || name == "" { return diff --git a/migrations/20231128_jellyfish_migration/verify/fetch_blobs.sh b/migrations/20231128_jellyfish_migration/verify/fetch_blobs.sh index 6d1ee37f99..d5c9126a1b 100644 --- a/migrations/20231128_jellyfish_migration/verify/fetch_blobs.sh +++ b/migrations/20231128_jellyfish_migration/verify/fetch_blobs.sh @@ -1,7 +1,7 @@ #!/bin/bash JSON_FILE=$1 OUTPUT_DIR=$2 -LOG_PREFIX=prod_blob +LOG_PREFIX=prod_blob_series check_val() { if [[ -z "$1" ]]; then @@ -30,13 +30,13 @@ check_val $SESSION_TOKEN "SESSION_TOKEN" ## enbale downloading o counter=0 -jq -c '.[]' $JSON_FILE | while read i; do +jq -c ' reverse .[]' $JSON_FILE | while read i; do - counter=$((counter+1)) + # counter=$((counter+1)) - if [[ "$counter" == 12 ]]; then - # reset counter - counter=0 + # # if [[ "$counter" == 2 ]]; then + # # # reset counter + # # counter=0 DEVICE_ID=$(jq -r '.deviceId' <<<"$i") check_val $DEVICE_ID "DEVICE_ID" @@ -77,5 +77,5 @@ jq -c '.[]' $JSON_FILE | while read i; do fi fi fi - fi + # fi done diff --git a/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh b/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh index 02235e79a6..630210a30f 100644 --- a/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh +++ b/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh @@ -1,11 +1,21 @@ #!/bin/bash -BLOBS_DIR=~/Documents/tmp/prd_blobs/tandem + USER_ID=6a452338-5064-4795-81ca-84957bad2280 -USER_EMAIL=$1 -USER_PW=$2 +USER_EMAIL=jamie+platform_upload@tidepool.org +USER_PW=$1 LOG_PREFIX=prod_blob -for filename in $BLOBS_DIR*/**/*blob*.gz; do +DEVICE_TYPE=$2 +if [[ -z "$DEVICE_TYPE" ]]; then + DEVICE_TYPE=InsOmn + USER_ID=04afa5f8-9cb4-4824-9d76-67fa8740da2b + USER_EMAIL=jamie+jellyfish_upload@tidepool.org +fi + +BLOBS_DIR=~/Documents/tmp/prd_blobs/${DEVICE_TYPE} +SECRET=$(op item get "qa3 server secret" --account tidepool.1password.com --fields label=credential --format json | jq -r '.value') + +for filename in $BLOBS_DIR*/*blob*.gz; do if grep -wq "$filename" "${LOG_PREFIX}_upload.log"; then echo "$filename already uploaded so cleaning up" @@ -15,12 +25,8 @@ for filename in $BLOBS_DIR*/**/*blob*.gz; do elif grep -wq "$filename" "${LOG_PREFIX}_error.log"; then echo "$filename already failed to upload" else - - SECRET=$(op item get "qa3 server secret" --account tidepool.1password.com --fields label=credential --format json | jq -r '.value') SERVER_TOKEN="$(curl -s -I -X POST -H "X-Tidepool-Server-Secret: $SECRET" -H "X-Tidepool-Server-Name: devops" "https://${API_ENV}.tidepool.org/auth/serverlogin" | grep 'x-tidepool-session-token' | sed 's/[^:]*: //')" - source ./upload_blob.sh "$filename" "$USER_EMAIL" "$USER_PW" "$LOG_PREFIX" source ./cleanup_user_data.sh "$USER_ID" "$SERVER_TOKEN" - fi done diff --git a/migrations/20231128_jellyfish_migration/verify/upload_blob.sh b/migrations/20231128_jellyfish_migration/verify/upload_blob.sh index 4f03fd0ebe..4e094bf5b9 100644 --- a/migrations/20231128_jellyfish_migration/verify/upload_blob.sh +++ b/migrations/20231128_jellyfish_migration/verify/upload_blob.sh @@ -16,7 +16,7 @@ check_val() { } cd $UPLOADER_DIR - +# config file exists in the uploader repo source ./config/qa3.sh check_val $BLOB_FILE "BLOB_FILE" @@ -58,15 +58,19 @@ if [ "$SUCCESS" = true ]; then echo "$records" else echo 'upload failed!' - - error_details=$(echo "$output" | grep -A100000 'add data to dataset failed' | grep -B100000 'Offending record for error') - + + error_details=$(echo "$output" | grep -A100000 'add data to dataset failed' | grep -B100000 'Offending record for error 0') + + if [[ -z "$error_details" ]]; then + error_details=$(echo "$output" | grep -A100000 'add data to dataset failed' | grep -B100000 'upload.toPlatform: failed') + fi + if [[ -z "$error_details" ]]; then error_details=$(echo "$output" | grep -A100000 'Error' | grep -B100000 '') fi - echo "{"blob":"$BLOB_FILE", "details":{$error_details}}" >>"$ERROR_LOG" + error_details=$(echo $error_details | tr -d '\n\t\r') + + echo "{"blob":"$BLOB_FILE", "details":{ "$error_details" }" >>"$ERROR_LOG" echo "$output" fi - - diff --git a/migrations/20231128_jellyfish_migration/verify/verify.go b/migrations/20231128_jellyfish_migration/verify/verify.go index af1c130f6e..b2bcfb0102 100644 --- a/migrations/20231128_jellyfish_migration/verify/verify.go +++ b/migrations/20231128_jellyfish_migration/verify/verify.go @@ -24,10 +24,12 @@ type config struct { mongoURI string findBlobs bool verifyDeduped bool + verifyDevice bool sameAccount bool platformUploadID string jellyfishUploadID string uploadIdDeduped string + deviceID string dataTypes string } @@ -37,7 +39,9 @@ const JellyfishUploadIDFlag = "upload-id-jellyfish" const SameAccountFlag = "same-account" const FindBlobFlag = "find-blobs" const VerifyDedupedFlag = "verify-deduped" +const VerifyDeviceFlag = "verify-device" const UploadIdDedupedFlag = "upload-id" +const DeviceIdFlag = "device-id" const DataTypesFlag = "data-types" const UseSubsetFlag = "use-subset" @@ -96,6 +100,18 @@ func (m *Verify) RunAndExit() { return m.verificationUtil.VerifyDeduped(m.config.uploadIdDeduped, strings.Split(m.config.dataTypes, ",")) } + if m.config.verifyDevice { + m.verificationUtil, err = NewDataVerify( + m.ctx, + m.client.Database("data").Collection("deviceData"), + ) + + if err != nil { + return fmt.Errorf("unable to create verification utils : %w", err) + } + return m.verificationUtil.VerifyDeviceUploads(m.config.deviceID, strings.Split(m.config.dataTypes, ",")) + } + m.verificationUtil, err = NewDataVerify( m.ctx, m.client.Database("data").Collection("deviceData"), @@ -154,6 +170,12 @@ func (m *Verify) Initialize() error { Destination: &m.config.uploadIdDeduped, Required: false, }, + cli.StringFlag{ + Name: DeviceIdFlag, + Usage: "deviceID of the datasets to check", + Destination: &m.config.deviceID, + Required: false, + }, cli.StringFlag{ Name: DataTypesFlag, Usage: "comma seperated list of data types to compare", @@ -173,6 +195,12 @@ func (m *Verify) Initialize() error { Destination: &m.config.verifyDeduped, Required: false, }, + cli.BoolFlag{ + Name: VerifyDeviceFlag, + Usage: "verify a device datasets", + Destination: &m.config.verifyDevice, + Required: false, + }, cli.StringFlag{ Name: MongoURIFlag, Usage: "mongo connection URI", From e6c765ddf12a1d37ff957d083a84a1a478b1431b Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 2 Sep 2024 16:02:06 +1200 Subject: [PATCH 394/413] fix hash tests --- data/deduplicator/deduplicator/hash_test.go | 23 +++++++++++---------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/data/deduplicator/deduplicator/hash_test.go b/data/deduplicator/deduplicator/hash_test.go index 700b3ce6c7..908bdf7ec1 100644 --- a/data/deduplicator/deduplicator/hash_test.go +++ b/data/deduplicator/deduplicator/hash_test.go @@ -65,9 +65,9 @@ var _ = Describe("Hash", func() { It("returns an error when any datum returns an error getting legacy identity fields", func() { dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} - dataSetDataTest[0].GetTypeOutputs = []string{"test-type"} + dataSetDataTest[0].GetTypeOutputs = []string{} dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: nil, Error: errors.New("test error")}} - dataSetDataTest[1].GetTypeOutputs = []string{"test-type"} + dataSetDataTest[1].GetTypeOutputs = []string{} Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, legacyOpts)).To(MatchError("unable to gather legacy identity fields for datum *test.Datum; test error")) }) @@ -79,9 +79,9 @@ var _ = Describe("Hash", func() { It("returns an error when any datum returns no legacy identity fields", func() { dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} - dataSetDataTest[0].GetTypeOutputs = []string{"test-type"} + dataSetDataTest[0].GetTypeOutputs = []string{} dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: nil, Error: nil}} - dataSetDataTest[1].GetTypeOutputs = []string{"test-type"} + dataSetDataTest[1].GetTypeOutputs = []string{} Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, legacyOpts)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity fields are missing")) }) @@ -93,9 +93,9 @@ var _ = Describe("Hash", func() { It("returns an error when any datum returns empty legacy identity fields", func() { dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} - dataSetDataTest[0].GetTypeOutputs = []string{"test-type"} + dataSetDataTest[0].GetTypeOutputs = []string{} dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{}, Error: nil}} - dataSetDataTest[1].GetTypeOutputs = []string{"test-type"} + dataSetDataTest[1].GetTypeOutputs = []string{} Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, legacyOpts)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity fields are missing")) }) @@ -107,9 +107,9 @@ var _ = Describe("Hash", func() { It("returns an error when any datum returns any empty legacy identity fields", func() { dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} - dataSetDataTest[0].GetTypeOutputs = []string{"test-type"} + dataSetDataTest[0].GetTypeOutputs = []string{} dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), ""}, Error: nil}} - dataSetDataTest[1].GetTypeOutputs = []string{"test-type"} + dataSetDataTest[1].GetTypeOutputs = []string{} Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, legacyOpts)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity field is empty")) }) @@ -127,6 +127,7 @@ var _ = Describe("Hash", func() { }) It("returns successfully", func() { + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, defaultOpts)).To(Succeed()) }) }) @@ -134,11 +135,11 @@ var _ = Describe("Hash", func() { Context("with legacy identity fields", func() { BeforeEach(func() { dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{"test", "0"}, Error: nil}} - dataSetDataTest[0].GetTypeOutputs = []string{"test-type"} + dataSetDataTest[0].GetTypeOutputs = []string{} dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{"test", "1"}, Error: nil}} - dataSetDataTest[1].GetTypeOutputs = []string{"test-type"} + dataSetDataTest[1].GetTypeOutputs = []string{} dataSetDataTest[2].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{"test", "2"}, Error: nil}} - dataSetDataTest[2].GetTypeOutputs = []string{"test-type"} + dataSetDataTest[2].GetTypeOutputs = []string{} }) AfterEach(func() { From 7f84ab880efae0d9802ed209815effa9d8122e78 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 5 Sep 2024 12:06:11 +1200 Subject: [PATCH 395/413] include userID in device data query --- .../verify/data_verify.go | 23 ++++++++++--------- .../verify/verify.go | 19 +++++++++++---- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/verify/data_verify.go b/migrations/20231128_jellyfish_migration/verify/data_verify.go index 77e117e045..a99375b4f1 100644 --- a/migrations/20231128_jellyfish_migration/verify/data_verify.go +++ b/migrations/20231128_jellyfish_migration/verify/data_verify.go @@ -102,7 +102,7 @@ func (m *DataVerify) fetchDataSetNotDeduped(uploadID string, dataTypes []string) return typeSet, nil } -func (m *DataVerify) fetchDeviceData(deviceID string, dataTypes []string) (map[string][]map[string]interface{}, error) { +func (m *DataVerify) fetchDeviceData(userID string, deviceID string, dataTypes []string) (map[string][]map[string]interface{}, error) { if m.dataC == nil { return nil, errors.New("missing data collection") } @@ -114,6 +114,7 @@ func (m *DataVerify) fetchDeviceData(deviceID string, dataTypes []string) (map[s dset := []map[string]interface{}{} filter := bson.M{ + "_userId": userID, "deviceId": deviceID, "type": dType, } @@ -378,12 +379,12 @@ func (m *DataVerify) VerifyUploadDifferences(platformUploadID string, jellyfishU return nil } -func (m *DataVerify) VerifyDeduped(uploadID string, dataTyes []string) error { +func (m *DataVerify) VerifyDeduped(uploadID string, dataTypes []string) error { - if len(dataTyes) == 0 { - dataTyes = DatasetTypes + if len(dataTypes) == 0 { + dataTypes = DatasetTypes } - dataset, err := m.fetchDataSetNotDeduped(uploadID, dataTyes) + dataset, err := m.fetchDataSetNotDeduped(uploadID, dataTypes) if err != nil { return err } @@ -400,21 +401,21 @@ func (m *DataVerify) VerifyDeduped(uploadID string, dataTyes []string) error { return nil } -func (m *DataVerify) VerifyDeviceUploads(deviceID string, dataTyes []string) error { +func (m *DataVerify) VerifyDeviceUploads(userID string, deviceID string, dataTypes []string) error { - if len(dataTyes) == 0 { - dataTyes = DatasetTypes + if len(dataTypes) == 0 { + dataTypes = DatasetTypes } - datasets, err := m.fetchDeviceData(deviceID, dataTyes) + datasets, err := m.fetchDeviceData(userID, deviceID, dataTypes) if err != nil { return err } if len(datasets) != 0 { - notDedupedPath := filepath.Join(".", "_device_data", deviceID) + deviceDataPath := filepath.Join(".", "_device_data", deviceID) for dType, dTypeItems := range datasets { if len(dTypeItems) > 0 { - writeFileData(dTypeItems, notDedupedPath, fmt.Sprintf("%s_data.json", dType), true) + writeFileData(dTypeItems, deviceDataPath, fmt.Sprintf("%s_data.json", dType), true) } } } diff --git a/migrations/20231128_jellyfish_migration/verify/verify.go b/migrations/20231128_jellyfish_migration/verify/verify.go index b2bcfb0102..3bb8c1cb56 100644 --- a/migrations/20231128_jellyfish_migration/verify/verify.go +++ b/migrations/20231128_jellyfish_migration/verify/verify.go @@ -30,6 +30,7 @@ type config struct { jellyfishUploadID string uploadIdDeduped string deviceID string + userID string dataTypes string } @@ -40,8 +41,9 @@ const SameAccountFlag = "same-account" const FindBlobFlag = "find-blobs" const VerifyDedupedFlag = "verify-deduped" const VerifyDeviceFlag = "verify-device" -const UploadIdDedupedFlag = "upload-id" -const DeviceIdFlag = "device-id" +const UploadIDFlag = "upload-id" +const DeviceIDFlag = "device-id" +const UserIDFlag = "user-id" const DataTypesFlag = "data-types" const UseSubsetFlag = "use-subset" @@ -75,6 +77,7 @@ func (m *Verify) RunAndExit() { return fmt.Errorf("unable to connect to MongoDB: %w", err) } defer m.client.Disconnect(m.ctx) + log.Printf("using config %#v", m.config) if m.config.findBlobs { m.verificationUtil, err = NewDataVerify( @@ -109,7 +112,7 @@ func (m *Verify) RunAndExit() { if err != nil { return fmt.Errorf("unable to create verification utils : %w", err) } - return m.verificationUtil.VerifyDeviceUploads(m.config.deviceID, strings.Split(m.config.dataTypes, ",")) + return m.verificationUtil.VerifyDeviceUploads(m.config.userID, m.config.deviceID, strings.Split(m.config.dataTypes, ",")) } m.verificationUtil, err = NewDataVerify( @@ -165,17 +168,23 @@ func (m *Verify) Initialize() error { Required: false, }, cli.StringFlag{ - Name: UploadIdDedupedFlag, + Name: UploadIDFlag, Usage: "uploadID of the dataset to check deduping of", Destination: &m.config.uploadIdDeduped, Required: false, }, cli.StringFlag{ - Name: DeviceIdFlag, + Name: DeviceIDFlag, Usage: "deviceID of the datasets to check", Destination: &m.config.deviceID, Required: false, }, + cli.StringFlag{ + Name: UserIDFlag, + Usage: "userID of the device to check", + Destination: &m.config.userID, + Required: false, + }, cli.StringFlag{ Name: DataTypesFlag, Usage: "comma seperated list of data types to compare", From 5c6b8fddfac296854d6a23c7b1c8290513c0a152 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 10 Sep 2024 15:02:29 +1200 Subject: [PATCH 396/413] set raw data from CBG, fix issue with missing id for SMBG --- .../glucose/continuous/continuous_test.go | 28 +++++++++++++----- data/types/blood/glucose/glucose.go | 6 ++-- data/types/blood/glucose/glucose_test.go | 29 ++++++++++++++----- .../glucose/selfmonitored/selfmonitored.go | 6 +--- 4 files changed, 45 insertions(+), 24 deletions(-) diff --git a/data/types/blood/glucose/continuous/continuous_test.go b/data/types/blood/glucose/continuous/continuous_test.go index 4a3bfda9d4..3c49045bea 100644 --- a/data/types/blood/glucose/continuous/continuous_test.go +++ b/data/types/blood/glucose/continuous/continuous_test.go @@ -11,6 +11,8 @@ import ( dataTypesBloodGlucoseTest "github.com/tidepool-org/platform/data/types/blood/glucose/test" dataTypesTest "github.com/tidepool-org/platform/data/types/test" errorsTest "github.com/tidepool-org/platform/errors/test" + "github.com/tidepool-org/platform/metadata" + metadataTest "github.com/tidepool-org/platform/metadata/test" "github.com/tidepool-org/platform/pointer" "github.com/tidepool-org/platform/structure" structureValidator "github.com/tidepool-org/platform/structure/validator" @@ -265,6 +267,7 @@ var _ = Describe("Continuous", func() { Context("Normalize", func() { DescribeTable("normalizes the datum", func(units *string, mutator func(datum *continuous.Continuous, units *string), expectator func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string)) { + for _, origin := range structure.Origins() { datum := NewContinuous(units) mutator(datum, units) @@ -274,6 +277,7 @@ var _ = Describe("Continuous", func() { datum.Normalize(normalizer.WithOrigin(origin)) Expect(normalizer.Error()).To(BeNil()) Expect(normalizer.Data()).To(BeEmpty()) + expectedDatum.Raw = metadataTest.CloneMetadata(datum.Raw) if expectator != nil { expectator(datum, expectedDatum, units) } @@ -313,17 +317,19 @@ var _ = Describe("Continuous", func() { ) DescribeTable("normalizes the datum with origin external", - func(units *string, mutator func(datum *continuous.Continuous, units *string), expectator func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string)) { + func(units *string, mutator func(datum *continuous.Continuous, units *string), expectator func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string, value *float64)) { datum := NewContinuous(units) mutator(datum, units) + originalValue := pointer.CloneFloat64(datum.Value) expectedDatum := CloneContinuous(datum) normalizer := dataNormalizer.New() Expect(normalizer).ToNot(BeNil()) datum.Normalize(normalizer.WithOrigin(structure.OriginExternal)) Expect(normalizer.Error()).To(BeNil()) Expect(normalizer.Data()).To(BeEmpty()) + expectedDatum.Raw = metadataTest.CloneMetadata(datum.Raw) if expectator != nil { - expectator(datum, expectedDatum, units) + expectator(datum, expectedDatum, units, originalValue) } Expect(datum).To(Equal(expectedDatum)) }, @@ -345,45 +351,51 @@ var _ = Describe("Continuous", func() { Entry("modifies the datum; units mmol/l", pointer.FromString("mmol/l"), func(datum *continuous.Continuous, units *string) {}, - func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string) { + func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string, value *float64) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) + dataBloodGlucoseTest.ExpectRaw(datum.Raw, &metadata.Metadata{"units": *units, "value": *value}) }, ), Entry("modifies the datum; units mmol/l; value missing", pointer.FromString("mmol/l"), func(datum *continuous.Continuous, units *string) { datum.Value = nil }, - func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string) { + func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string, value *float64) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) + dataBloodGlucoseTest.ExpectRaw(datum.Raw, &metadata.Metadata{"units": *units, "value": nil}) }, ), Entry("modifies the datum; units mg/dL", pointer.FromString("mg/dL"), func(datum *continuous.Continuous, units *string) {}, - func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string) { + func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string, value *float64) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) dataBloodGlucoseTest.ExpectNormalizedValue(datum.Value, expectedDatum.Value, units) + dataBloodGlucoseTest.ExpectRaw(datum.Raw, &metadata.Metadata{"units": *units, "value": *value}) }, ), Entry("modifies the datum; units mg/dL; value missing", pointer.FromString("mg/dL"), func(datum *continuous.Continuous, units *string) { datum.Value = nil }, - func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string) { + func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string, value *float64) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) + dataBloodGlucoseTest.ExpectRaw(datum.Raw, &metadata.Metadata{"units": *units, "value": nil}) }, ), Entry("modifies the datum; units mg/dl", pointer.FromString("mg/dl"), func(datum *continuous.Continuous, units *string) {}, - func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string) { + func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string, value *float64) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) dataBloodGlucoseTest.ExpectNormalizedValue(datum.Value, expectedDatum.Value, units) + dataBloodGlucoseTest.ExpectRaw(datum.Raw, &metadata.Metadata{"units": *units, "value": *value}) }, ), Entry("modifies the datum; units mg/dl; value missing", pointer.FromString("mg/dl"), func(datum *continuous.Continuous, units *string) { datum.Value = nil }, - func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string) { + func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string, value *float64) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) + dataBloodGlucoseTest.ExpectRaw(datum.Raw, &metadata.Metadata{"units": *units, "value": nil}) }, ), ) diff --git a/data/types/blood/glucose/glucose.go b/data/types/blood/glucose/glucose.go index 422db011c7..6dc6935c16 100644 --- a/data/types/blood/glucose/glucose.go +++ b/data/types/blood/glucose/glucose.go @@ -28,8 +28,8 @@ func (g *Glucose) Normalize(normalizer data.Normalizer) { g.Blood.Normalize(normalizer) if normalizer.Origin() == structure.OriginExternal { - units := g.Units - g.Units = dataBloodGlucose.NormalizeUnits(units) - g.Value = dataBloodGlucose.NormalizeValueForUnits(g.Value, units) + g.SetRawValueAndUnits(g.Value, g.Units) + g.Value = dataBloodGlucose.NormalizeValueForUnits(g.Value, g.Units) + g.Units = dataBloodGlucose.NormalizeUnits(g.Units) } } diff --git a/data/types/blood/glucose/glucose_test.go b/data/types/blood/glucose/glucose_test.go index 96348dc1f5..6b1847cb67 100644 --- a/data/types/blood/glucose/glucose_test.go +++ b/data/types/blood/glucose/glucose_test.go @@ -12,6 +12,8 @@ import ( dataTypesBloodGlucoseTest "github.com/tidepool-org/platform/data/types/blood/glucose/test" dataTypesTest "github.com/tidepool-org/platform/data/types/test" errorsTest "github.com/tidepool-org/platform/errors/test" + "github.com/tidepool-org/platform/metadata" + metadataTest "github.com/tidepool-org/platform/metadata/test" "github.com/tidepool-org/platform/pointer" "github.com/tidepool-org/platform/structure" structureValidator "github.com/tidepool-org/platform/structure/validator" @@ -285,6 +287,7 @@ var _ = Describe("Glucose", func() { Context("Normalize", func() { DescribeTable("normalizes the datum", func(units *string, mutator func(datum *glucose.Glucose, units *string), expectator func(datum *glucose.Glucose, expectedDatum *glucose.Glucose, units *string)) { + for _, origin := range structure.Origins() { datum := dataTypesBloodGlucoseTest.NewGlucose(units) mutator(datum, units) @@ -294,6 +297,7 @@ var _ = Describe("Glucose", func() { datum.Normalize(normalizer.WithOrigin(origin)) Expect(normalizer.Error()).To(BeNil()) Expect(normalizer.Data()).To(BeEmpty()) + expectedDatum.Raw = metadataTest.CloneMetadata(datum.Raw) if expectator != nil { expectator(datum, expectedDatum, units) } @@ -323,17 +327,19 @@ var _ = Describe("Glucose", func() { ) DescribeTable("normalizes the datum with origin external", - func(units *string, mutator func(datum *glucose.Glucose, units *string), expectator func(datum *glucose.Glucose, expectedDatum *glucose.Glucose, units *string)) { + func(units *string, mutator func(datum *glucose.Glucose, units *string), expectator func(datum *glucose.Glucose, expectedDatum *glucose.Glucose, units *string, value *float64)) { datum := dataTypesBloodGlucoseTest.NewGlucose(units) mutator(datum, units) + originalValue := pointer.CloneFloat64(datum.Value) expectedDatum := dataTypesBloodGlucoseTest.CloneGlucose(datum) normalizer := dataNormalizer.New() Expect(normalizer).ToNot(BeNil()) datum.Normalize(normalizer.WithOrigin(structure.OriginExternal)) Expect(normalizer.Error()).To(BeNil()) Expect(normalizer.Data()).To(BeEmpty()) + expectedDatum.Raw = metadataTest.CloneMetadata(datum.Raw) if expectator != nil { - expectator(datum, expectedDatum, units) + expectator(datum, expectedDatum, units, originalValue) } Expect(datum).To(Equal(expectedDatum)) }, @@ -360,15 +366,17 @@ var _ = Describe("Glucose", func() { Entry("modifies the datum; units mmol/l", pointer.FromString("mmol/l"), func(datum *glucose.Glucose, units *string) {}, - func(datum *glucose.Glucose, expectedDatum *glucose.Glucose, units *string) { + func(datum *glucose.Glucose, expectedDatum *glucose.Glucose, units *string, value *float64) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) + dataBloodGlucoseTest.ExpectRaw(datum.Raw, &metadata.Metadata{"units": *units, "value": *value}) }, ), Entry("modifies the datum; units mmol/l; value missing", pointer.FromString("mmol/l"), func(datum *glucose.Glucose, units *string) { datum.Value = nil }, - func(datum *glucose.Glucose, expectedDatum *glucose.Glucose, units *string) { + func(datum *glucose.Glucose, expectedDatum *glucose.Glucose, units *string, value *float64) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) + dataBloodGlucoseTest.ExpectRaw(datum.Raw, &metadata.Metadata{"units": *units, "value": nil}) }, ), Entry("modifies the datum; units mg/dL", @@ -376,16 +384,18 @@ var _ = Describe("Glucose", func() { func(datum *glucose.Glucose, units *string) { datum.Value = pointer.FromFloat64(test.RandomFloat64FromRange(dataBloodGlucose.ValueRangeForUnits(units))) }, - func(datum *glucose.Glucose, expectedDatum *glucose.Glucose, units *string) { + func(datum *glucose.Glucose, expectedDatum *glucose.Glucose, units *string, value *float64) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) dataBloodGlucoseTest.ExpectNormalizedValue(datum.Value, expectedDatum.Value, units) + dataBloodGlucoseTest.ExpectRaw(datum.Raw, &metadata.Metadata{"units": *units, "value": *value}) }, ), Entry("modifies the datum; units mg/dL; value missing", pointer.FromString("mg/dL"), func(datum *glucose.Glucose, units *string) { datum.Value = nil }, - func(datum *glucose.Glucose, expectedDatum *glucose.Glucose, units *string) { + func(datum *glucose.Glucose, expectedDatum *glucose.Glucose, units *string, value *float64) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) + dataBloodGlucoseTest.ExpectRaw(datum.Raw, &metadata.Metadata{"units": *units, "value": nil}) }, ), Entry("modifies the datum; units mg/dl", @@ -393,16 +403,19 @@ var _ = Describe("Glucose", func() { func(datum *glucose.Glucose, units *string) { datum.Value = pointer.FromFloat64(test.RandomFloat64FromRange(dataBloodGlucose.ValueRangeForUnits(units))) }, - func(datum *glucose.Glucose, expectedDatum *glucose.Glucose, units *string) { + func(datum *glucose.Glucose, expectedDatum *glucose.Glucose, units *string, value *float64) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) dataBloodGlucoseTest.ExpectNormalizedValue(datum.Value, expectedDatum.Value, units) + dataBloodGlucoseTest.ExpectRaw(datum.Raw, &metadata.Metadata{"units": *units, "value": *value}) }, ), Entry("modifies the datum; units mg/dl; value missing", pointer.FromString("mg/dl"), func(datum *glucose.Glucose, units *string) { datum.Value = nil }, - func(datum *glucose.Glucose, expectedDatum *glucose.Glucose, units *string) { + func(datum *glucose.Glucose, expectedDatum *glucose.Glucose, units *string, value *float64) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) + + dataBloodGlucoseTest.ExpectRaw(datum.Raw, &metadata.Metadata{"units": *units, "value": nil}) }, ), ) diff --git a/data/types/blood/glucose/selfmonitored/selfmonitored.go b/data/types/blood/glucose/selfmonitored/selfmonitored.go index 567369d8fe..9faea94eed 100644 --- a/data/types/blood/glucose/selfmonitored/selfmonitored.go +++ b/data/types/blood/glucose/selfmonitored/selfmonitored.go @@ -66,11 +66,7 @@ func (s *SelfMonitored) Normalize(normalizer data.Normalizer) { normalizer = normalizer.WithMeta(s.Meta()) } - if normalizer.Origin() == structure.OriginExternal { - s.SetRawValueAndUnits(s.Value, s.Units) - s.Value = dataBloodGlucose.NormalizeValueForUnits(s.Value, s.Units) - s.Units = dataBloodGlucose.NormalizeUnits(s.Units) - } + s.Glucose.Normalize(normalizer) } func (s *SelfMonitored) LegacyIdentityFields() ([]string, error) { From cabab88e9e7579630b80c012019a86daac02c43a Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 23 Sep 2024 17:15:12 +1200 Subject: [PATCH 397/413] updates to helper files --- .../20231128_jellyfish_migration/readme.md | 21 ++++++++++++++++++- .../verify/process_all_blobs.sh | 4 ++-- .../verify/upload_blob.sh | 6 ++---- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/migrations/20231128_jellyfish_migration/readme.md b/migrations/20231128_jellyfish_migration/readme.md index a21b15ca52..a4dc508ce9 100644 --- a/migrations/20231128_jellyfish_migration/readme.md +++ b/migrations/20231128_jellyfish_migration/readme.md @@ -41,4 +41,23 @@ GLOBAL OPTIONS: { "$project": { "blobId": "$client.private.blobId", "_userId": 1, "deviceId": 1}}, { "$group": { "_id": "$_userId", "detail": { "$push": "$$ROOT" }}} ] -``` \ No newline at end of file +``` + +- finding error types + +grep -c "InsOmn.*Checksum" prod_blob_error.log +grep -c "InsOmn.*rawdata" prod_blob_error.log +grep -c "InsOmn.*value-not-exists" prod_blob_error.log +grep -c "InsOmn.*value-out-of-range" prod_blob_error.log + +grep -c "tandem" prod_blob_error.log + + +cat prod_blob_upload.log | grep "InsOmn" | sed -n 's/.*records: \([0-9]*\).*/\1/p' | awk '{sum+=$1} END {print sum}' +cat prod_blob_upload.log | grep "InsOmn" | sed -n 's/.*upload \([0-9]*\).*/\1/p' | awk '{sum+=$1} END {print sum}' + +cat prod_blob_upload.log | grep "tandem" | sed -n 's/.*records: \([0-9]*\).*/\1/p' | awk '{sum+=$1} END {print sum}' +cat prod_blob_upload.log | grep "tandem" | sed -n 's/.*upload \([0-9]*\).*/\1/p' | awk '{sum+=$1} END {print sum}' + + + diff --git a/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh b/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh index 630210a30f..da848d4f08 100644 --- a/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh +++ b/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh @@ -3,11 +3,11 @@ USER_ID=6a452338-5064-4795-81ca-84957bad2280 USER_EMAIL=jamie+platform_upload@tidepool.org USER_PW=$1 -LOG_PREFIX=prod_blob +LOG_PREFIX=qa_blob DEVICE_TYPE=$2 if [[ -z "$DEVICE_TYPE" ]]; then - DEVICE_TYPE=InsOmn + DEVICE_TYPE=tandem USER_ID=04afa5f8-9cb4-4824-9d76-67fa8740da2b USER_EMAIL=jamie+jellyfish_upload@tidepool.org fi diff --git a/migrations/20231128_jellyfish_migration/verify/upload_blob.sh b/migrations/20231128_jellyfish_migration/verify/upload_blob.sh index 4e094bf5b9..42fbd8d078 100644 --- a/migrations/20231128_jellyfish_migration/verify/upload_blob.sh +++ b/migrations/20231128_jellyfish_migration/verify/upload_blob.sh @@ -58,7 +58,6 @@ if [ "$SUCCESS" = true ]; then echo "$records" else echo 'upload failed!' - error_details=$(echo "$output" | grep -A100000 'add data to dataset failed' | grep -B100000 'Offending record for error 0') if [[ -z "$error_details" ]]; then @@ -66,11 +65,10 @@ else fi if [[ -z "$error_details" ]]; then - error_details=$(echo "$output" | grep -A100000 'Error' | grep -B100000 '') + error_details=$(echo "$output") fi error_details=$(echo $error_details | tr -d '\n\t\r') - echo "{"blob":"$BLOB_FILE", "details":{ "$error_details" }" >>"$ERROR_LOG" - echo "$output" + echo "{"blob":"$BLOB_FILE", "details": {"$error_details"}" >>"$ERROR_LOG" fi From 5dbfcab2d9b9a7bbf600447c075347a4a1795a16 Mon Sep 17 00:00:00 2001 From: Jamie Bate Date: Wed, 25 Sep 2024 09:25:02 +1200 Subject: [PATCH 398/413] increase carb ratio based on findings from prod data testing (#767) * increase carb ratio based on findings from prod data testing * allow the duration of a combo to be zero or greater with a non-zero expectedDuration --- data/types/bolus/combination/combination.go | 77 +- .../bolus/combination/combination_test.go | 1211 ++++++----------- data/types/bolus/extended/extended.go | 3 - data/types/bolus/extended/extended_test.go | 114 +- data/types/bolus/normal/normal.go | 3 - data/types/bolus/normal/normal_test.go | 45 +- data/types/calculator/calculator.go | 2 +- data/types/calculator/calculator_test.go | 50 +- data/types/calculator/recommended.go | 2 +- data/types/calculator/recommended_test.go | 10 +- .../settings/pump/carbohydrate_ratio_start.go | 2 +- .../pump/carbohydrate_ratio_start_test.go | 14 +- 12 files changed, 533 insertions(+), 1000 deletions(-) diff --git a/data/types/bolus/combination/combination.go b/data/types/bolus/combination/combination.go index 19ca3dab69..40dd571c50 100644 --- a/data/types/bolus/combination/combination.go +++ b/data/types/bolus/combination/combination.go @@ -60,67 +60,32 @@ func (c *Combination) Validate(validator structure.Validator) { validator.String("subType", &c.SubType).EqualTo(SubType) } - if c.NormalExpected != nil { - validator.Int("duration", c.Duration).Exists().EqualTo(DurationMinimum) - validator.Int("expectedDuration", c.DurationExpected).Exists().InRange(DurationMinimum, DurationMaximum) - validator.Float64("extended", c.Extended).Exists().EqualTo(ExtendedMinimum) - extendedExpectedValidator := validator.Float64("expectedExtended", c.ExtendedExpected) - extendedExpectedValidator.InRange(ExtendedMinimum, ExtendedMaximum) - if c.Normal != nil { - if *c.Normal == NormalMinimum { - if c.ExtendedExpected == nil { - validator.Float64("expectedNormal", c.NormalExpected).GreaterThan(NormalMinimum) - } - extendedExpectedValidator.GreaterThan(ExtendedMinimum) - } else { - extendedExpectedValidator.Exists() - } - } + validator.Int("duration", c.Duration).Exists().InRange(DurationMinimum, DurationMaximum) + durationExpectedValidator := validator.Int("expectedDuration", c.DurationExpected) + if c.Duration != nil && *c.Duration >= DurationMinimum && *c.Duration <= DurationMaximum { + durationExpectedValidator.InRange(*c.Duration, DurationMaximum) + } else { + durationExpectedValidator.InRange(DurationMinimum, DurationMaximum) + } + if c.ExtendedExpected != nil { + durationExpectedValidator.Exists() } else { - validator.Int("duration", c.Duration).Exists().InRange(DurationMinimum, DurationMaximum) - expectedDurationValidator := validator.Int("expectedDuration", c.DurationExpected) - if c.Duration != nil && *c.Duration >= DurationMinimum && *c.Duration <= DurationMaximum { - expectedDurationValidator.InRange(*c.Duration, DurationMaximum) - } else { - expectedDurationValidator.InRange(DurationMinimum, DurationMaximum) - } - if c.ExtendedExpected != nil { - expectedDurationValidator.Exists() - } else { - expectedDurationValidator.NotExists() - } - validator.Float64("extended", c.Extended).Exists().InRange(ExtendedMinimum, ExtendedMaximum) - expectedExtendedValidator := validator.Float64("expectedExtended", c.ExtendedExpected) - if c.Extended != nil && *c.Extended >= ExtendedMinimum && *c.Extended <= ExtendedMaximum { - if *c.Extended == ExtendedMinimum { - if c.Normal != nil && *c.Normal == NormalMinimum { - expectedExtendedValidator.GreaterThan(ExtendedMinimum) - } - expectedExtendedValidator.Exists() - } - expectedExtendedValidator.InRange(*c.Extended, ExtendedMaximum) - } else { - expectedExtendedValidator.InRange(ExtendedMinimum, ExtendedMaximum) - } + durationExpectedValidator.NotExists() } + validator.Float64("extended", c.Extended).Exists().InRange(ExtendedMinimum, ExtendedMaximum) + extendedExpectedValidator := validator.Float64("expectedExtended", c.ExtendedExpected) + if c.Extended != nil && *c.Extended >= ExtendedMinimum && *c.Extended <= ExtendedMaximum { + extendedExpectedValidator.InRange(*c.Extended, ExtendedMaximum) + } else { + extendedExpectedValidator.InRange(ExtendedMinimum, ExtendedMaximum) + } + validator.Float64("normal", c.Normal).Exists().InRange(NormalMinimum, NormalMaximum) - expectedNormalValidator := validator.Float64("expectedNormal", c.NormalExpected) + normalExpectedValidator := validator.Float64("expectedNormal", c.NormalExpected) if c.Normal != nil && *c.Normal >= NormalMinimum && *c.Normal <= NormalMaximum { - if *c.Normal == NormalMinimum { - // If Normal is zero, then _either_: - if c.Extended != nil { - if c.NormalExpected == nil { - validator.Float64("extended", c.Extended).GreaterThanOrEqualTo(ExtendedMinimum) - } else { - validator.Float64("extended", c.Extended).Exists() - } - } else { - expectedNormalValidator.GreaterThan(NormalMinimum) - } - } - expectedNormalValidator.InRange(*c.Normal, NormalMaximum) + normalExpectedValidator.InRange(*c.Normal, NormalMaximum) } else { - expectedNormalValidator.InRange(NormalMinimum, NormalMaximum) + normalExpectedValidator.InRange(NormalMinimum, NormalMaximum) } } diff --git a/data/types/bolus/combination/combination_test.go b/data/types/bolus/combination/combination_test.go index feec5f4741..7484f5f5e8 100644 --- a/data/types/bolus/combination/combination_test.go +++ b/data/types/bolus/combination/combination_test.go @@ -10,7 +10,6 @@ import ( "github.com/tidepool-org/platform/pointer" "github.com/tidepool-org/platform/structure" structureValidator "github.com/tidepool-org/platform/structure/validator" - "github.com/tidepool-org/platform/test" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -84,11 +83,11 @@ var _ = Describe("Combination", func() { ), Entry("type missing", func(datum *combination.Combination) { datum.Type = "" }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueEmpty(), "/type", &bolus.Meta{SubType: "dual/square"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueEmpty(), "/type", &bolus.Meta{SubType: combination.SubType}), ), Entry("type invalid", func(datum *combination.Combination) { datum.Type = "invalidType" }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidType", "bolus"), "/type", &bolus.Meta{Type: "invalidType", SubType: "dual/square"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidType", "bolus"), "/type", &bolus.Meta{Type: "invalidType", SubType: combination.SubType}), ), Entry("type bolus", func(datum *combination.Combination) { datum.Type = "bolus" }, @@ -99,1069 +98,653 @@ var _ = Describe("Combination", func() { ), Entry("sub type invalid", func(datum *combination.Combination) { datum.SubType = "invalidSubType" }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidSubType", "dual/square"), "/subType", &bolus.Meta{Type: "bolus", SubType: "invalidSubType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidSubType", combination.SubType), "/subType", &bolus.Meta{Type: "bolus", SubType: "invalidSubType"}), ), Entry("sub type dual/square", - func(datum *combination.Combination) { datum.SubType = "dual/square" }, + func(datum *combination.Combination) { datum.SubType = combination.SubType }, ), - Entry("normal expected missing; duration missing; duration expected missing", + Entry("normal missing; normal expected missing", func(datum *combination.Combination) { - datum.Duration = nil - datum.DurationExpected = nil - datum.ExtendedExpected = nil + datum.Normal = nil + datum.NormalExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), + ), + Entry("normal missing; normal expected out of range (lower)", + func(datum *combination.Combination) { + datum.Normal = nil + datum.NormalExpected = pointer.FromFloat64(-0.1) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, combination.NormalMinimum, combination.NormalMaximum), "/expectedNormal", NewMeta()), + ), + Entry("normal missing; normal expected in range (lower)", + func(datum *combination.Combination) { + datum.Normal = nil + datum.NormalExpected = pointer.FromFloat64(0.0) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), + ), + Entry("normal missing; normal expected in range (upper)", + func(datum *combination.Combination) { + datum.Normal = nil + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), + ), + Entry("normal missing; normal expected out of range (upper)", + func(datum *combination.Combination) { + datum.Normal = nil + datum.NormalExpected = pointer.FromFloat64(250.1) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.NormalMinimum, combination.NormalMaximum), "/expectedNormal", NewMeta()), + ), + Entry("normal out of range (lower); normal expected missing", + func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(-0.1) + datum.NormalExpected = nil + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, combination.NormalMinimum, combination.NormalMaximum), "/normal", NewMeta()), + ), + Entry("normal out of range (lower); normal expected out of range (lower)", + func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(-0.1) + datum.NormalExpected = pointer.FromFloat64(-0.1) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, combination.NormalMinimum, combination.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, combination.NormalMinimum, combination.NormalMaximum), "/expectedNormal", NewMeta()), + ), + Entry("normal out of range (lower); normal expected in range (lower)", + func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(-0.1) + datum.NormalExpected = pointer.FromFloat64(0.0) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, combination.NormalMinimum, combination.NormalMaximum), "/normal", NewMeta()), + ), + Entry("normal out of range (lower); normal expected in range (upper)", + func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(-0.1) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, combination.NormalMinimum, combination.NormalMaximum), "/normal", NewMeta()), + ), + Entry("normal out of range (lower); normal expected out of range (upper)", + func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(-0.1) + datum.NormalExpected = pointer.FromFloat64(250.1) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, combination.NormalMinimum, combination.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.NormalMinimum, combination.NormalMaximum), "/expectedNormal", NewMeta()), + ), + Entry("normal in range (lower); normal expected out of range (lower)", + func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(0.0) + datum.NormalExpected = pointer.FromFloat64(-0.1) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, combination.NormalMinimum, combination.NormalMaximum), "/expectedNormal", NewMeta()), + ), + Entry("normal in range (lower); normal expected in range (lower)", + func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(0.0) + datum.NormalExpected = pointer.FromFloat64(0.0) + }, + ), + Entry("normal in range (lower); normal expected in range (upper)", + func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(0.0) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) + }, + ), + Entry("normal in range (lower); normal expected out of range (upper)", + func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(0.0) + datum.NormalExpected = pointer.FromFloat64(250.1) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.NormalMinimum, combination.NormalMaximum), "/expectedNormal", NewMeta()), + ), + Entry("normal in range (upper); normal expected missing", + func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = nil + }, + ), + Entry("normal in range (upper); normal expected out of range (lower)", + func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(249.9) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(249.9, combination.NormalMaximum, combination.NormalMaximum), "/expectedNormal", NewMeta()), + ), + Entry("normal in range (upper); normal expected in range (lower)", + func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) + }, + ), + Entry("normal in range (upper); normal expected in range (upper)", + func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) + }, + ), + Entry("normal in range (upper); normal expected out of range (upper)", + func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(250.1) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.NormalMaximum, combination.NormalMaximum), "/expectedNormal", NewMeta()), + ), + Entry("normal out of range (upper); normal expected missing", + func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(250.1) + datum.NormalExpected = nil + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.NormalMinimum, combination.NormalMaximum), "/normal", NewMeta()), + ), + Entry("normal out of range (upper); normal expected out of range (lower)", + func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(250.1) + datum.NormalExpected = pointer.FromFloat64(-0.1) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.NormalMinimum, combination.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, combination.NormalMinimum, combination.NormalMaximum), "/expectedNormal", NewMeta()), + ), + Entry("normal out of range (upper); normal expected in range (lower)", + func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(250.1) + datum.NormalExpected = pointer.FromFloat64(0.0) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.NormalMinimum, combination.NormalMaximum), "/normal", NewMeta()), ), - Entry("normal expected missing; duration missing; duration expected out of range (lower)", + Entry("normal out of range (upper); normal expected in range (upper)", + func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(250.1) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.NormalMinimum, combination.NormalMaximum), "/normal", NewMeta()), + ), + Entry("normal out of range (upper); normal expected out of range (upper)", + func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(250.1) + datum.NormalExpected = pointer.FromFloat64(250.1) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.NormalMinimum, combination.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.NormalMinimum, combination.NormalMaximum), "/expectedNormal", NewMeta()), + ), + Entry("duration missing; duration expected out of range (lower)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Duration = nil datum.DurationExpected = pointer.FromInt(-1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, combination.DurationMaximum), "/expectedDuration", NewMeta()), ), - Entry("normal expected missing; duration missing; duration expected in range (lower)", + Entry("duration missing; duration expected in range (lower)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Duration = nil datum.DurationExpected = pointer.FromInt(0) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", NewMeta()), ), - Entry("normal expected missing; duration missing; duration expected in range (upper)", + Entry("duration missing; duration expected in range (upper)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Duration = nil - datum.DurationExpected = pointer.FromInt(86400000) + datum.DurationExpected = pointer.FromInt(combination.DurationMaximum) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", NewMeta()), ), - Entry("normal expected missing; duration missing; duration expected out of range (upper)", + Entry("duration missing; duration expected out of range (upper)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Duration = nil datum.DurationExpected = pointer.FromInt(86400001) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, combination.DurationMaximum), "/expectedDuration", NewMeta()), ), - Entry("normal expected missing; duration out of range (lower); duration expected missing", + Entry("duration out of range (lower); duration expected missing", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Duration = pointer.FromInt(-1) datum.DurationExpected = nil datum.ExtendedExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, combination.DurationMaximum), "/duration", NewMeta()), ), - Entry("normal expected missing; duration out of range (lower); duration expected out of range (lower)", + Entry("duration out of range (lower); duration expected out of range (lower)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Duration = pointer.FromInt(-1) datum.DurationExpected = pointer.FromInt(-1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, combination.DurationMaximum), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, combination.DurationMaximum), "/expectedDuration", NewMeta()), ), - Entry("normal expected missing; duration out of range (lower); duration expected in range (lower)", + Entry("duration out of range (lower); duration expected in range (lower)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Duration = pointer.FromInt(-1) datum.DurationExpected = pointer.FromInt(0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, combination.DurationMaximum), "/duration", NewMeta()), ), - Entry("normal expected missing; duration out of range (lower); duration expected in range (upper)", + Entry("duration out of range (lower); duration expected in range (upper)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Duration = pointer.FromInt(-1) - datum.DurationExpected = pointer.FromInt(86400000) + datum.DurationExpected = pointer.FromInt(combination.DurationMaximum) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, combination.DurationMaximum), "/duration", NewMeta()), ), - Entry("normal expected missing; duration out of range (lower); duration expected out of range (upper)", + Entry("duration out of range (lower); duration expected out of range (upper)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Duration = pointer.FromInt(-1) datum.DurationExpected = pointer.FromInt(86400001) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, combination.DurationMaximum), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, combination.DurationMaximum), "/expectedDuration", NewMeta()), ), - Entry("normal expected missing; duration in range (lower); duration expected missing", + Entry("duration in range (lower); duration expected missing", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Duration = pointer.FromInt(0) datum.DurationExpected = nil datum.ExtendedExpected = nil }, ), - Entry("normal expected missing; duration in range (lower); duration expected out of range (lower)", + Entry("duration in range (lower); duration expected out of range (lower)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Duration = pointer.FromInt(0) datum.DurationExpected = pointer.FromInt(-1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, combination.DurationMaximum), "/expectedDuration", NewMeta()), ), - Entry("normal expected missing; duration in range (lower); duration expected in range (lower)", + Entry("duration in range (lower); duration expected in range (lower)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Duration = pointer.FromInt(0) datum.DurationExpected = pointer.FromInt(0) }, ), - Entry("normal expected missing; duration in range (lower); duration expected in range (upper)", + Entry("duration in range (lower); duration expected in range (upper)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Duration = pointer.FromInt(0) - datum.DurationExpected = pointer.FromInt(86400000) + datum.DurationExpected = pointer.FromInt(combination.DurationMaximum) }, ), - Entry("normal expected missing; duration in range (lower); duration expected out of range (upper)", + Entry("duration in range (lower); duration expected out of range (upper)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Duration = pointer.FromInt(0) datum.DurationExpected = pointer.FromInt(86400001) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, combination.DurationMaximum), "/expectedDuration", NewMeta()), ), - Entry("normal expected missing; duration in range (upper); duration expected missing", + Entry("duration in range (upper); duration expected missing", func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(86400000) + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) + datum.Duration = pointer.FromInt(combination.DurationMaximum) datum.DurationExpected = nil datum.ExtendedExpected = nil }, ), - Entry("normal expected missing; duration in range (upper); duration expected out of range (lower)", + Entry("duration in range (upper); duration expected out of range (lower)", func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(86400000) - datum.DurationExpected = pointer.FromInt(86399999) + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) + datum.Duration = pointer.FromInt(combination.DurationMaximum) + datum.DurationExpected = pointer.FromInt(604799999) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86399999, 86400000, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604799999, combination.DurationMaximum, combination.DurationMaximum), "/expectedDuration", NewMeta()), ), - Entry("normal expected missing; duration in range (upper); duration expected in range (lower)", + Entry("duration in range (upper); duration expected in range (lower)", func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(86400000) - datum.DurationExpected = pointer.FromInt(86400000) + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) + datum.Duration = pointer.FromInt(combination.DurationMaximum) + datum.DurationExpected = pointer.FromInt(combination.DurationMaximum) }, ), - Entry("normal expected missing; duration in range (upper); duration expected in range (upper)", + Entry("duration in range (upper); duration expected in range (upper)", func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(86400000) - datum.DurationExpected = pointer.FromInt(86400000) + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) + datum.Duration = pointer.FromInt(combination.DurationMaximum) + datum.DurationExpected = pointer.FromInt(combination.DurationMaximum) }, ), - Entry("normal expected missing; duration in range (upper); duration expected out of range (upper)", + Entry("duration in range (upper); duration expected out of range (upper)", func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(86400000) + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) + datum.Duration = pointer.FromInt(combination.DurationMaximum) datum.DurationExpected = pointer.FromInt(86400001) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 86400000, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, combination.DurationMaximum, combination.DurationMaximum), "/expectedDuration", NewMeta()), ), - Entry("normal expected missing; duration out of range (upper); duration expected missing", + Entry("duration out of range (upper); duration expected missing", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Duration = pointer.FromInt(86400001) datum.DurationExpected = nil datum.ExtendedExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, combination.DurationMaximum), "/duration", NewMeta()), ), - Entry("normal expected missing; duration out of range (upper); duration expected out of range (lower)", + Entry("duration out of range (upper); duration expected out of range (lower)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Duration = pointer.FromInt(86400001) datum.DurationExpected = pointer.FromInt(-1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, combination.DurationMaximum), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, combination.DurationMaximum), "/expectedDuration", NewMeta()), ), - Entry("normal expected missing; duration out of range (upper); duration expected in range (lower)", + Entry("duration out of range (upper); duration expected in range (lower)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Duration = pointer.FromInt(86400001) datum.DurationExpected = pointer.FromInt(0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, combination.DurationMaximum), "/duration", NewMeta()), ), - Entry("normal expected missing; duration out of range (upper); duration expected in range (upper)", + Entry("duration out of range (upper); duration expected in range (upper)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Duration = pointer.FromInt(86400001) - datum.DurationExpected = pointer.FromInt(86400000) + datum.DurationExpected = pointer.FromInt(combination.DurationMaximum) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, combination.DurationMaximum), "/duration", NewMeta()), ), - Entry("normal expected missing; duration out of range (upper); duration expected out of range (upper)", + Entry("duration out of range (upper); duration expected out of range (upper)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Duration = pointer.FromInt(86400001) datum.DurationExpected = pointer.FromInt(86400001) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, combination.DurationMaximum), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, combination.DurationMaximum), "/expectedDuration", NewMeta()), ), - Entry("normal expected missing; extended missing; extended expected missing", + Entry("extended missing; extended expected missing", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.DurationExpected = nil datum.Extended = nil datum.ExtendedExpected = nil }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), ), - Entry("normal expected missing; extended missing; extended expected out of range (lower)", + Entry("extended missing; extended expected out of range (lower)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Extended = nil datum.ExtendedExpected = pointer.FromFloat64(-0.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, combination.ExtendedMinimum, combination.ExtendedMaximum), "/expectedExtended", NewMeta()), ), - Entry("normal expected missing; extended missing; extended expected in range (lower)", + Entry("extended missing; extended expected in range (lower)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Extended = nil datum.ExtendedExpected = pointer.FromFloat64(0.0) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), ), - Entry("normal expected missing; extended missing; extended expected in range (upper)", + Entry("extended missing; extended expected in range (upper)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Extended = nil - datum.ExtendedExpected = pointer.FromFloat64(250.0) + datum.ExtendedExpected = pointer.FromFloat64(combination.ExtendedMaximum) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), ), - Entry("normal expected missing; extended missing; extended expected out of range (upper)", + Entry("extended missing; extended expected out of range (upper)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Extended = nil datum.ExtendedExpected = pointer.FromFloat64(250.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.ExtendedMinimum, combination.ExtendedMaximum), "/expectedExtended", NewMeta()), ), - Entry("normal expected missing; extended out of range (lower); extended expected missing", + Entry("extended out of range (lower); extended expected missing", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.DurationExpected = nil datum.Extended = pointer.FromFloat64(-0.1) datum.ExtendedExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, combination.ExtendedMinimum, combination.ExtendedMaximum), "/extended", NewMeta()), ), - Entry("normal expected missing; extended out of range (lower); extended expected out of range (lower)", + Entry("extended out of range (lower); extended expected out of range (lower)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Extended = pointer.FromFloat64(-0.1) datum.ExtendedExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, combination.ExtendedMinimum, combination.ExtendedMaximum), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, combination.ExtendedMinimum, combination.ExtendedMaximum), "/expectedExtended", NewMeta()), ), - Entry("normal expected missing; extended out of range (lower); extended expected in range (lower)", + Entry("extended out of range (lower); extended expected in range (lower)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Extended = pointer.FromFloat64(-0.1) datum.ExtendedExpected = pointer.FromFloat64(0.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, combination.ExtendedMinimum, combination.ExtendedMaximum), "/extended", NewMeta()), ), - Entry("normal expected missing; extended out of range (lower); extended expected in range (upper)", + Entry("extended out of range (lower); extended expected in range (upper)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Extended = pointer.FromFloat64(-0.1) - datum.ExtendedExpected = pointer.FromFloat64(250.0) + datum.ExtendedExpected = pointer.FromFloat64(combination.ExtendedMaximum) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, combination.ExtendedMinimum, combination.ExtendedMaximum), "/extended", NewMeta()), ), - Entry("normal expected missing; extended out of range (lower); extended expected out of range (upper)", + Entry("extended out of range (lower); extended expected out of range (upper)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Extended = pointer.FromFloat64(-0.1) datum.ExtendedExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedExtended", NewMeta()), - ), - Entry("normal expected missing; extended in range (lower); extended expected missing", - func(datum *combination.Combination) { - datum.DurationExpected = nil - datum.Extended = pointer.FromFloat64(0.0) - datum.ExtendedExpected = nil - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, combination.ExtendedMinimum, combination.ExtendedMaximum), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.ExtendedMinimum, combination.ExtendedMaximum), "/expectedExtended", NewMeta()), ), - Entry("normal expected missing; extended in range (lower); extended expected out of range (lower)", + Entry("extended in range (lower); extended expected out of range (lower)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Extended = pointer.FromFloat64(0.0) datum.ExtendedExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, combination.ExtendedMinimum, combination.ExtendedMaximum), "/expectedExtended", NewMeta()), ), - Entry("normal expected missing; extended in range (lower); extended expected in range (lower)", + Entry("extended in range (lower); extended expected in range (lower)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Extended = pointer.FromFloat64(0.0) datum.ExtendedExpected = pointer.FromFloat64(0.0) }, ), - Entry("normal expected missing; extended in range (lower); extended expected in range (upper)", + Entry("extended in range (lower); extended expected in range (upper)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Extended = pointer.FromFloat64(0.0) - datum.ExtendedExpected = pointer.FromFloat64(250.0) + datum.ExtendedExpected = pointer.FromFloat64(combination.ExtendedMaximum) }, ), - Entry("normal expected missing; extended in range (lower); extended expected out of range (upper)", + Entry("extended in range (lower); extended expected out of range (upper)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Extended = pointer.FromFloat64(0.0) datum.ExtendedExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.ExtendedMinimum, combination.ExtendedMaximum), "/expectedExtended", NewMeta()), ), - Entry("normal expected missing; extended in range (upper); extended expected missing", + Entry("extended in range (upper); extended expected missing", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.DurationExpected = nil - datum.Extended = pointer.FromFloat64(250.0) + datum.Extended = pointer.FromFloat64(combination.ExtendedMaximum) datum.ExtendedExpected = nil }, ), - Entry("normal expected missing; extended in range (upper); extended expected out of range (lower)", + Entry("extended in range (upper); extended expected out of range (lower)", func(datum *combination.Combination) { - datum.Extended = pointer.FromFloat64(250.0) + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) + datum.Extended = pointer.FromFloat64(combination.ExtendedMaximum) datum.ExtendedExpected = pointer.FromFloat64(249.9) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(249.9, 250.0, 250.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(249.9, combination.ExtendedMaximum, combination.ExtendedMaximum), "/expectedExtended", NewMeta()), ), - Entry("normal expected missing; extended in range (upper); extended expected in range (lower)", + Entry("extended in range (upper); extended expected in range (lower)", func(datum *combination.Combination) { - datum.Extended = pointer.FromFloat64(250.0) - datum.ExtendedExpected = pointer.FromFloat64(250.0) + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) + datum.Extended = pointer.FromFloat64(combination.ExtendedMaximum) + datum.ExtendedExpected = pointer.FromFloat64(combination.ExtendedMaximum) }, ), - Entry("normal expected missing; extended in range (upper); extended expected in range (upper)", + Entry("extended in range (upper); extended expected in range (upper)", func(datum *combination.Combination) { - datum.Extended = pointer.FromFloat64(250.0) - datum.ExtendedExpected = pointer.FromFloat64(250.0) + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) + datum.Extended = pointer.FromFloat64(combination.ExtendedMaximum) + datum.ExtendedExpected = pointer.FromFloat64(combination.ExtendedMaximum) }, ), - Entry("normal expected missing; extended in range (upper); extended expected out of range (upper)", + Entry("extended in range (upper); extended expected out of range (upper)", func(datum *combination.Combination) { - datum.Extended = pointer.FromFloat64(250.0) + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) + datum.Extended = pointer.FromFloat64(combination.ExtendedMaximum) datum.ExtendedExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 250.0, 250.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.ExtendedMaximum, combination.ExtendedMaximum), "/expectedExtended", NewMeta()), ), - Entry("normal expected missing; extended out of range (upper); extended expected missing", + Entry("extended out of range (upper); extended expected missing", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.DurationExpected = nil datum.Extended = pointer.FromFloat64(250.1) datum.ExtendedExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.ExtendedMinimum, combination.ExtendedMaximum), "/extended", NewMeta()), ), - Entry("normal expected missing; extended out of range (upper); extended expected out of range (lower)", + Entry("extended out of range (upper); extended expected out of range (lower)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Extended = pointer.FromFloat64(250.1) datum.ExtendedExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.ExtendedMinimum, combination.ExtendedMaximum), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, combination.ExtendedMinimum, combination.ExtendedMaximum), "/expectedExtended", NewMeta()), ), - Entry("normal expected missing; extended out of range (upper); extended expected in range (lower)", + Entry("extended out of range (upper); extended expected in range (lower)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Extended = pointer.FromFloat64(250.1) datum.ExtendedExpected = pointer.FromFloat64(0.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.ExtendedMinimum, combination.ExtendedMaximum), "/extended", NewMeta()), ), - Entry("normal expected missing; extended out of range (upper); extended expected in range (upper)", + Entry("extended out of range (upper); extended expected in range (upper)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Extended = pointer.FromFloat64(250.1) - datum.ExtendedExpected = pointer.FromFloat64(250.0) + datum.ExtendedExpected = pointer.FromFloat64(combination.ExtendedMaximum) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.ExtendedMinimum, combination.ExtendedMaximum), "/extended", NewMeta()), ), - Entry("normal expected missing; extended out of range (upper); extended expected out of range (upper)", + Entry("extended out of range (upper); extended expected out of range (upper)", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.Extended = pointer.FromFloat64(250.1) datum.ExtendedExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.ExtendedMinimum, combination.ExtendedMaximum), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.ExtendedMinimum, combination.ExtendedMaximum), "/expectedExtended", NewMeta()), ), - Entry("normal expected missing; duration missing; extended expected missing", + Entry("duration missing; extended expected missing", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.DurationExpected = nil datum.ExtendedExpected = nil - datum.NormalExpected = nil }, ), - Entry("normal expected missing; duration missing; extended expected exists", + Entry("duration missing; extended expected exists", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) datum.DurationExpected = nil - datum.NormalExpected = nil + datum.ExtendedExpected = pointer.FromFloat64(combination.ExtendedMaximum) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/expectedDuration", NewMeta()), ), - Entry("normal expected missing; duration exists; extended expected missing", + Entry("duration exists; extended expected missing", func(datum *combination.Combination) { + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) + datum.DurationExpected = pointer.FromInt(combination.DurationMaximum) datum.ExtendedExpected = nil - datum.NormalExpected = nil }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueExists(), "/expectedDuration", NewMeta()), ), - Entry("normal expected missing; duration exists; extended expected exists", - func(datum *combination.Combination) { - datum.DurationExpected = nil - datum.ExtendedExpected = nil - }, - ), - Entry("normal expected exists; duration missing; duration expected missing", - func(datum *combination.Combination) { - datum.Duration = nil - datum.DurationExpected = nil - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/expectedDuration", NewMeta()), - ), - Entry("normal expected exists; duration missing; duration expected out of range (lower)", - func(datum *combination.Combination) { - datum.Duration = nil - datum.DurationExpected = pointer.FromInt(-1) - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/expectedDuration", NewMeta()), - ), - Entry("normal expected exists; duration missing; duration expected in range (lower)", - func(datum *combination.Combination) { - datum.Duration = nil - datum.DurationExpected = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", NewMeta()), - ), - Entry("normal expected exists; duration missing; duration expected in range (upper)", - func(datum *combination.Combination) { - datum.Duration = nil - datum.DurationExpected = pointer.FromInt(86400000) - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", NewMeta()), - ), - Entry("normal expected exists; duration missing; duration expected out of range (upper)", - func(datum *combination.Combination) { - datum.Duration = nil - datum.DurationExpected = pointer.FromInt(86400001) - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/expectedDuration", NewMeta()), - ), - Entry("normal expected exists; duration out of range (lower); duration expected missing", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(-1) - datum.DurationExpected = nil - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(-1, 0), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/expectedDuration", NewMeta()), - ), - Entry("normal expected exists; duration out of range (lower); duration expected out of range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(-1) - datum.DurationExpected = pointer.FromInt(-1) - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(-1, 0), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/expectedDuration", NewMeta()), - ), - Entry("normal expected exists; duration out of range (lower); duration expected in range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(-1) - datum.DurationExpected = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(-1, 0), "/duration", NewMeta()), - ), - Entry("normal expected exists; duration out of range (lower); duration expected in range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(-1) - datum.DurationExpected = pointer.FromInt(86400000) - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(-1, 0), "/duration", NewMeta()), - ), - Entry("normal expected exists; duration out of range (lower); duration expected out of range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(-1) - datum.DurationExpected = pointer.FromInt(86400001) - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(-1, 0), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/expectedDuration", NewMeta()), - ), - Entry("normal expected exists; duration in range; duration expected missing", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.DurationExpected = nil - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/expectedDuration", NewMeta()), - ), - Entry("normal expected exists; duration in range; duration expected out of range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.DurationExpected = pointer.FromInt(-1) - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/expectedDuration", NewMeta()), - ), - Entry("normal expected exists; duration in range; duration expected in range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.DurationExpected = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - ), - Entry("normal expected exists; duration in range; duration expected in range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.DurationExpected = pointer.FromInt(86400000) - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - ), - Entry("normal expected exists; duration in range; duration expected out of range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.DurationExpected = pointer.FromInt(86400001) - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/expectedDuration", NewMeta()), - ), - Entry("normal expected exists; duration out of range (upper); duration expected missing", + Entry("duration exists; extended expected exists", func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(1) - datum.DurationExpected = nil - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(1, 0), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/expectedDuration", NewMeta()), - ), - Entry("normal expected exists; duration out of range (upper); duration expected out of range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(1) - datum.DurationExpected = pointer.FromInt(-1) - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(1, 0), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/expectedDuration", NewMeta()), - ), - Entry("normal expected exists; duration out of range (upper); duration expected in range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(1) - datum.DurationExpected = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(1, 0), "/duration", NewMeta()), - ), - Entry("normal expected exists; duration out of range (upper); duration expected in range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(1) - datum.DurationExpected = pointer.FromInt(86400000) - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(1, 0), "/duration", NewMeta()), - ), - Entry("normal expected exists; duration out of range (upper); duration expected out of range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(1) - datum.DurationExpected = pointer.FromInt(86400001) - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(1, 0), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/expectedDuration", NewMeta()), - ), - Entry("normal expected exists; extended missing; extended expected missing", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = nil - datum.ExtendedExpected = nil - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/expectedExtended", NewMeta()), - ), - Entry("normal expected exists; extended missing; extended expected out of range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = nil - datum.ExtendedExpected = pointer.FromFloat64(-0.1) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedExtended", NewMeta()), - ), - Entry("normal expected exists; extended missing; extended expected in range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = nil - datum.ExtendedExpected = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), - ), - Entry("normal expected exists; extended missing; extended expected in range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = nil - datum.ExtendedExpected = pointer.FromFloat64(250.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), - ), - Entry("normal expected exists; extended missing; extended expected out of range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = nil - datum.ExtendedExpected = pointer.FromFloat64(250.1) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedExtended", NewMeta()), - ), - Entry("normal expected exists; extended out of range (lower); extended expected missing", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(-0.1) - datum.ExtendedExpected = nil - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(-0.1, 0.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/expectedExtended", NewMeta()), - ), - Entry("normal expected exists; extended out of range (lower); extended expected out of range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(-0.1) - datum.ExtendedExpected = pointer.FromFloat64(-0.1) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(-0.1, 0.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedExtended", NewMeta()), - ), - Entry("normal expected exists; extended out of range (lower); extended expected in range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(-0.1) - datum.ExtendedExpected = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(-0.1, 0.0), "/extended", NewMeta()), - ), - Entry("normal expected exists; extended out of range (lower); extended expected in range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(-0.1) - datum.ExtendedExpected = pointer.FromFloat64(250.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(-0.1, 0.0), "/extended", NewMeta()), - ), - Entry("normal expected exists; extended out of range (lower); extended expected out of range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(-0.1) - datum.ExtendedExpected = pointer.FromFloat64(250.1) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(-0.1, 0.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedExtended", NewMeta()), - ), - Entry("normal expected exists; extended in range; extended expected missing", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.ExtendedExpected = nil - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/expectedExtended", NewMeta()), - ), - Entry("normal expected exists; extended in range; extended expected out of range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.ExtendedExpected = pointer.FromFloat64(-0.1) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0, 250.0), "/expectedExtended", NewMeta()), - ), - Entry("normal expected exists; extended in range; extended expected in range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.ExtendedExpected = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - ), - Entry("normal expected exists; extended in range; extended expected in range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.ExtendedExpected = pointer.FromFloat64(250.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - ), - Entry("normal expected exists; extended in range; extended expected out of range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.ExtendedExpected = pointer.FromFloat64(250.1) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0, 250.0), "/expectedExtended", NewMeta()), - ), - Entry("normal expected exists; extended out of range (upper); extended expected missing", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.1) - datum.ExtendedExpected = nil - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(0.1, 0.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/expectedExtended", NewMeta()), - ), - Entry("normal expected exists; extended out of range (upper); extended expected out of range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.1) - datum.ExtendedExpected = pointer.FromFloat64(-0.1) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(0.1, 0.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedExtended", NewMeta()), - ), - Entry("normal expected exists; extended out of range (upper); extended expected in range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.1) - datum.ExtendedExpected = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(0.1, 0.0), "/extended", NewMeta()), - ), - Entry("normal expected exists; extended out of range (upper); extended expected in range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.1) - datum.ExtendedExpected = pointer.FromFloat64(250.0) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(0.1, 0.0), "/extended", NewMeta()), - ), - Entry("normal expected exists; extended out of range (upper); extended expected out of range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.1) - datum.ExtendedExpected = pointer.FromFloat64(250.1) - datum.NormalExpected = pointer.FromFloat64(test.RandomFloat64FromRange(*datum.Normal, combination.NormalMaximum)) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo(0.1, 0.0), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedExtended", NewMeta()), - ), - Entry("normal in range (lower); extended in range (lower); normal expected in range (lower); extended expected out of range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(0.0) - datum.ExtendedExpected = pointer.FromFloat64(0.0) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotGreaterThan(0.0, 0.0), "/expectedExtended", NewMeta()), - ), - Entry("normal missing; normal expected missing", - func(datum *combination.Combination) { - datum.Normal = nil - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), - ), - Entry("normal missing; normal expected out of range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = nil - datum.NormalExpected = pointer.FromFloat64(-0.1) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedNormal", NewMeta()), - ), - Entry("normal missing; normal expected in range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = nil - datum.NormalExpected = pointer.FromFloat64(0.0) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), - ), - Entry("normal missing; normal expected in range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = nil - datum.NormalExpected = pointer.FromFloat64(250.0) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), - ), - Entry("normal missing; normal expected out of range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = nil - datum.NormalExpected = pointer.FromFloat64(250.1) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedNormal", NewMeta()), - ), - Entry("normal out of range (lower); normal expected missing", - func(datum *combination.Combination) { - datum.Normal = pointer.FromFloat64(-0.1) - datum.NormalExpected = nil - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/normal", NewMeta()), - ), - Entry("normal out of range (lower); normal expected out of range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(-0.1) - datum.NormalExpected = pointer.FromFloat64(-0.1) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedNormal", NewMeta()), - ), - Entry("normal out of range (lower); normal expected in range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(-0.1) - datum.NormalExpected = pointer.FromFloat64(0.0) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/normal", NewMeta()), - ), - Entry("normal out of range (lower); normal expected in range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(-0.1) - datum.NormalExpected = pointer.FromFloat64(250.0) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/normal", NewMeta()), - ), - Entry("normal out of range (lower); normal expected out of range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(-0.1) - datum.NormalExpected = pointer.FromFloat64(250.1) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedNormal", NewMeta()), - ), - Entry("normal in range (lower); normal expected missing, extended missing", - func(datum *combination.Combination) { - datum.Normal = pointer.FromFloat64(0.0) - datum.Extended = nil - datum.NormalExpected = nil - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), - ), - Entry("normal in range (lower); extended in range (lower); extended expected missing, normal expected out of range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0.0) - datum.Normal = pointer.FromFloat64(0.0) - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(0.0) - datum.ExtendedExpected = nil - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotGreaterThan(0.0, 0.0), "/expectedNormal", NewMeta()), - ), - Entry("normal in range (lower); extended in range (lower); extended expected missing, extended expected out of range (lower)", - func(datum *combination.Combination) { - datum.Normal = pointer.FromFloat64(0.0) - datum.Extended = pointer.FromFloat64(0.0) - datum.NormalExpected = nil - datum.ExtendedExpected = pointer.FromFloat64(0.0) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotGreaterThan(0.0, 0.0), "/expectedExtended", NewMeta()), - ), - Entry("normal in range (lower); normal expected in range, extended missing", - func(datum *combination.Combination) { - datum.Normal = pointer.FromFloat64(0.0) - datum.Duration = pointer.FromInt(0) - datum.Extended = nil - datum.NormalExpected = pointer.FromFloat64(1.0) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), - ), - Entry("normal in range (lower); normal expected out of range, extended missing", - func(datum *combination.Combination) { - datum.Normal = pointer.FromFloat64(0.0) - datum.Duration = pointer.FromInt(0) - datum.Extended = nil - datum.NormalExpected = pointer.FromFloat64(0.0) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotGreaterThan(0.0, 0.0), "/expectedNormal", NewMeta()), - ), - Entry("normal in range (lower); normal expected missing, extended in range", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Normal = pointer.FromFloat64(0.0) - datum.Extended = pointer.FromFloat64(1.0) - datum.NormalExpected = nil - }, - ), - Entry("normal in range (lower); normal expected out of range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(-0.1) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedNormal", NewMeta()), - ), - Entry("normal in range (lower); normal expected in range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(0.0) - }, - ), - Entry("normal in range (lower); normal expected in range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(250.0) - }, - ), - Entry("normal in range (lower); normal expected out of range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(250.1) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedNormal", NewMeta()), - ), - Entry("normal in range (upper); normal expected missing", - func(datum *combination.Combination) { - datum.Normal = pointer.FromFloat64(250.0) - datum.NormalExpected = nil - }, - ), - Entry("normal in range (upper); normal expected out of range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(250.0) - datum.NormalExpected = pointer.FromFloat64(249.9) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(249.9, 250.0, 250.0), "/expectedNormal", NewMeta()), - ), - Entry("normal in range (upper); normal expected in range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(250.0) - datum.NormalExpected = pointer.FromFloat64(250.0) - }, - ), - Entry("normal in range (upper); normal expected in range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(250.0) - datum.NormalExpected = pointer.FromFloat64(250.0) - }, - ), - Entry("normal in range (upper); normal expected out of range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(250.0) - datum.NormalExpected = pointer.FromFloat64(250.1) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 250.0, 250.0), "/expectedNormal", NewMeta()), - ), - Entry("normal out of range (upper); normal expected missing", - func(datum *combination.Combination) { - datum.Normal = pointer.FromFloat64(250.1) - datum.NormalExpected = nil - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/normal", NewMeta()), - ), - Entry("normal out of range (upper); normal expected out of range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(250.1) - datum.NormalExpected = pointer.FromFloat64(-0.1) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/expectedNormal", NewMeta()), - ), - Entry("normal out of range (upper); normal expected in range (lower)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(250.1) - datum.NormalExpected = pointer.FromFloat64(0.0) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/normal", NewMeta()), - ), - Entry("normal out of range (upper); normal expected in range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(250.1) - datum.NormalExpected = pointer.FromFloat64(250.0) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/normal", NewMeta()), - ), - Entry("normal out of range (upper); normal expected out of range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(250.1) - datum.NormalExpected = pointer.FromFloat64(250.1) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/expectedNormal", NewMeta()), - ), - Entry("allow normal and extended to be 0 when extended expected is missing", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(250.0) - datum.ExtendedExpected = nil - }, - ), - Entry("allow normal and extended to be 0 when normal expected is missing and extended expected is in range (upper)", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(0.0) - datum.NormalExpected = nil - datum.ExtendedExpected = pointer.FromFloat64(250.0) - }, - ), - Entry("allow normal and extended to be 0 when both normal expected and extended expected are in range", - func(datum *combination.Combination) { - datum.Duration = pointer.FromInt(0) - datum.Extended = pointer.FromFloat64(0.0) - datum.Normal = pointer.FromFloat64(0.0) - datum.NormalExpected = pointer.FromFloat64(250.0) + datum.Normal = pointer.FromFloat64(combination.NormalMaximum) + datum.NormalExpected = pointer.FromFloat64(combination.NormalMaximum) + datum.DurationExpected = pointer.FromInt(combination.DurationMaximum) + datum.ExtendedExpected = pointer.FromFloat64(combination.ExtendedMaximum) }, ), Entry("multiple errors", @@ -1176,13 +759,13 @@ var _ = Describe("Combination", func() { datum.NormalExpected = pointer.FromFloat64(250.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidType", "bolus"), "/type", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidSubType", "dual/square"), "/subType", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidSubType", combination.SubType), "/subType", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/expectedDuration", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, combination.DurationMaximum), "/expectedDuration", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0, 250), "/expectedExtended", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.ExtendedMinimum, combination.ExtendedMaximum), "/expectedExtended", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0, 250), "/expectedNormal", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, combination.NormalMinimum, combination.NormalMaximum), "/expectedNormal", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), ), ) }) diff --git a/data/types/bolus/extended/extended.go b/data/types/bolus/extended/extended.go index a843de25fd..e7f438612f 100644 --- a/data/types/bolus/extended/extended.go +++ b/data/types/bolus/extended/extended.go @@ -69,9 +69,6 @@ func (e *Extended) Validate(validator structure.Validator) { validator.Float64("extended", e.Extended).Exists().InRange(ExtendedMinimum, ExtendedMaximum) extendedExpectedValidator := validator.Float64("expectedExtended", e.ExtendedExpected) if e.Extended != nil && *e.Extended >= ExtendedMinimum && *e.Extended <= ExtendedMaximum { - if *e.Extended == ExtendedMinimum { - extendedExpectedValidator.Exists() - } extendedExpectedValidator.InRange(*e.Extended, ExtendedMaximum) } else { extendedExpectedValidator.InRange(ExtendedMinimum, ExtendedMaximum) diff --git a/data/types/bolus/extended/extended_test.go b/data/types/bolus/extended/extended_test.go index 60c126488a..25b944c55d 100644 --- a/data/types/bolus/extended/extended_test.go +++ b/data/types/bolus/extended/extended_test.go @@ -108,7 +108,7 @@ var _ = Describe("Extended", func() { datum.DurationExpected = pointer.FromInt(-1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, extended.DurationMaximum), "/expectedDuration", NewMeta()), ), Entry("duration missing; duration expected in range (lower)", func(datum *extended.Extended) { @@ -120,7 +120,7 @@ var _ = Describe("Extended", func() { Entry("duration missing; duration expected in range (upper)", func(datum *extended.Extended) { datum.Duration = nil - datum.DurationExpected = pointer.FromInt(86400000) + datum.DurationExpected = pointer.FromInt(extended.DurationMaximum) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", NewMeta()), ), @@ -130,7 +130,7 @@ var _ = Describe("Extended", func() { datum.DurationExpected = pointer.FromInt(86400001) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, extended.DurationMaximum), "/expectedDuration", NewMeta()), ), Entry("duration out of range (lower); duration expected missing", func(datum *extended.Extended) { @@ -138,37 +138,37 @@ var _ = Describe("Extended", func() { datum.DurationExpected = nil datum.ExtendedExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, extended.DurationMaximum), "/duration", NewMeta()), ), Entry("duration out of range (lower); duration expected out of range (lower)", func(datum *extended.Extended) { datum.Duration = pointer.FromInt(-1) datum.DurationExpected = pointer.FromInt(-1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, extended.DurationMaximum), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, extended.DurationMaximum), "/expectedDuration", NewMeta()), ), Entry("duration out of range (lower); duration expected in range (lower)", func(datum *extended.Extended) { datum.Duration = pointer.FromInt(-1) datum.DurationExpected = pointer.FromInt(0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, extended.DurationMaximum), "/duration", NewMeta()), ), Entry("duration out of range (lower); duration expected in range (upper)", func(datum *extended.Extended) { datum.Duration = pointer.FromInt(-1) - datum.DurationExpected = pointer.FromInt(86400000) + datum.DurationExpected = pointer.FromInt(extended.DurationMaximum) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, extended.DurationMaximum), "/duration", NewMeta()), ), Entry("duration out of range (lower); duration expected out of range (upper)", func(datum *extended.Extended) { datum.Duration = pointer.FromInt(-1) datum.DurationExpected = pointer.FromInt(86400001) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, extended.DurationMaximum), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, extended.DurationMaximum), "/expectedDuration", NewMeta()), ), Entry("duration in range (lower); duration expected missing", func(datum *extended.Extended) { @@ -182,7 +182,7 @@ var _ = Describe("Extended", func() { datum.Duration = pointer.FromInt(0) datum.DurationExpected = pointer.FromInt(-1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, extended.DurationMaximum), "/expectedDuration", NewMeta()), ), Entry("duration in range (lower); duration expected in range (lower)", func(datum *extended.Extended) { @@ -193,7 +193,7 @@ var _ = Describe("Extended", func() { Entry("duration in range (lower); duration expected in range (upper)", func(datum *extended.Extended) { datum.Duration = pointer.FromInt(0) - datum.DurationExpected = pointer.FromInt(86400000) + datum.DurationExpected = pointer.FromInt(extended.DurationMaximum) }, ), Entry("duration in range (lower); duration expected out of range (upper)", @@ -201,40 +201,40 @@ var _ = Describe("Extended", func() { datum.Duration = pointer.FromInt(0) datum.DurationExpected = pointer.FromInt(86400001) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, extended.DurationMaximum), "/expectedDuration", NewMeta()), ), Entry("duration in range (upper); duration expected missing", func(datum *extended.Extended) { - datum.Duration = pointer.FromInt(86400000) + datum.Duration = pointer.FromInt(extended.DurationMaximum) datum.DurationExpected = nil datum.ExtendedExpected = nil }, ), Entry("duration in range (upper); duration expected out of range (lower)", func(datum *extended.Extended) { - datum.Duration = pointer.FromInt(86400000) + datum.Duration = pointer.FromInt(extended.DurationMaximum) datum.DurationExpected = pointer.FromInt(604799999) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604799999, 86400000, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604799999, extended.DurationMaximum, extended.DurationMaximum), "/expectedDuration", NewMeta()), ), Entry("duration in range (upper); duration expected in range (lower)", func(datum *extended.Extended) { - datum.Duration = pointer.FromInt(86400000) - datum.DurationExpected = pointer.FromInt(86400000) + datum.Duration = pointer.FromInt(extended.DurationMaximum) + datum.DurationExpected = pointer.FromInt(extended.DurationMaximum) }, ), Entry("duration in range (upper); duration expected in range (upper)", func(datum *extended.Extended) { - datum.Duration = pointer.FromInt(86400000) - datum.DurationExpected = pointer.FromInt(86400000) + datum.Duration = pointer.FromInt(extended.DurationMaximum) + datum.DurationExpected = pointer.FromInt(extended.DurationMaximum) }, ), Entry("duration in range (upper); duration expected out of range (upper)", func(datum *extended.Extended) { - datum.Duration = pointer.FromInt(86400000) + datum.Duration = pointer.FromInt(extended.DurationMaximum) datum.DurationExpected = pointer.FromInt(86400001) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 86400000, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, extended.DurationMaximum, extended.DurationMaximum), "/expectedDuration", NewMeta()), ), Entry("duration out of range (upper); duration expected missing", func(datum *extended.Extended) { @@ -242,37 +242,37 @@ var _ = Describe("Extended", func() { datum.DurationExpected = nil datum.ExtendedExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, extended.DurationMaximum), "/duration", NewMeta()), ), Entry("duration out of range (upper); duration expected out of range (lower)", func(datum *extended.Extended) { datum.Duration = pointer.FromInt(86400001) datum.DurationExpected = pointer.FromInt(-1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, extended.DurationMaximum), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, extended.DurationMaximum), "/expectedDuration", NewMeta()), ), Entry("duration out of range (upper); duration expected in range (lower)", func(datum *extended.Extended) { datum.Duration = pointer.FromInt(86400001) datum.DurationExpected = pointer.FromInt(0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, extended.DurationMaximum), "/duration", NewMeta()), ), Entry("duration out of range (upper); duration expected in range (upper)", func(datum *extended.Extended) { datum.Duration = pointer.FromInt(86400001) - datum.DurationExpected = pointer.FromInt(86400000) + datum.DurationExpected = pointer.FromInt(extended.DurationMaximum) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, extended.DurationMaximum), "/duration", NewMeta()), ), Entry("duration out of range (upper); duration expected out of range (upper)", func(datum *extended.Extended) { datum.Duration = pointer.FromInt(86400001) datum.DurationExpected = pointer.FromInt(86400001) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, extended.DurationMaximum), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, extended.DurationMaximum), "/expectedDuration", NewMeta()), ), Entry("extended missing; extended expected missing", func(datum *extended.Extended) { @@ -288,7 +288,7 @@ var _ = Describe("Extended", func() { datum.ExtendedExpected = pointer.FromFloat64(-0.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, extended.ExtendedMinimum, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), ), Entry("extended missing; extended expected in range (lower)", func(datum *extended.Extended) { @@ -310,7 +310,7 @@ var _ = Describe("Extended", func() { datum.ExtendedExpected = pointer.FromFloat64(250.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, extended.ExtendedMinimum, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), ), Entry("extended out of range (lower); extended expected missing", func(datum *extended.Extended) { @@ -318,52 +318,44 @@ var _ = Describe("Extended", func() { datum.Extended = pointer.FromFloat64(-0.1) datum.ExtendedExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, extended.ExtendedMinimum, extended.ExtendedMaximum), "/extended", NewMeta()), ), Entry("extended out of range (lower); extended expected out of range (lower)", func(datum *extended.Extended) { datum.Extended = pointer.FromFloat64(-0.1) datum.ExtendedExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, extended.ExtendedMinimum, extended.ExtendedMaximum), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, extended.ExtendedMinimum, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), ), Entry("extended out of range (lower); extended expected in range (lower)", func(datum *extended.Extended) { datum.Extended = pointer.FromFloat64(-0.1) datum.ExtendedExpected = pointer.FromFloat64(0.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, extended.ExtendedMinimum, extended.ExtendedMaximum), "/extended", NewMeta()), ), Entry("extended out of range (lower); extended expected in range (upper)", func(datum *extended.Extended) { datum.Extended = pointer.FromFloat64(-0.1) datum.ExtendedExpected = pointer.FromFloat64(extended.ExtendedMaximum) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, extended.ExtendedMinimum, extended.ExtendedMaximum), "/extended", NewMeta()), ), Entry("extended out of range (lower); extended expected out of range (upper)", func(datum *extended.Extended) { datum.Extended = pointer.FromFloat64(-0.1) datum.ExtendedExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), - ), - Entry("extended in range (lower); extended expected missing", - func(datum *extended.Extended) { - datum.DurationExpected = nil - datum.Extended = pointer.FromFloat64(0.0) - datum.ExtendedExpected = nil - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, extended.ExtendedMinimum, extended.ExtendedMaximum), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, extended.ExtendedMinimum, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), ), Entry("extended in range (lower); extended expected out of range (lower)", func(datum *extended.Extended) { datum.Extended = pointer.FromFloat64(0.0) datum.ExtendedExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, extended.ExtendedMinimum, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), ), Entry("extended in range (lower); extended expected in range (lower)", func(datum *extended.Extended) { @@ -382,7 +374,7 @@ var _ = Describe("Extended", func() { datum.Extended = pointer.FromFloat64(0.0) datum.ExtendedExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, extended.ExtendedMinimum, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), ), Entry("extended in range (upper); extended expected missing", func(datum *extended.Extended) { @@ -423,37 +415,37 @@ var _ = Describe("Extended", func() { datum.Extended = pointer.FromFloat64(250.1) datum.ExtendedExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, extended.ExtendedMinimum, extended.ExtendedMaximum), "/extended", NewMeta()), ), Entry("extended out of range (upper); extended expected out of range (lower)", func(datum *extended.Extended) { datum.Extended = pointer.FromFloat64(250.1) datum.ExtendedExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, extended.ExtendedMinimum, extended.ExtendedMaximum), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, extended.ExtendedMinimum, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), ), Entry("extended out of range (upper); extended expected in range (lower)", func(datum *extended.Extended) { datum.Extended = pointer.FromFloat64(250.1) datum.ExtendedExpected = pointer.FromFloat64(0.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, extended.ExtendedMinimum, extended.ExtendedMaximum), "/extended", NewMeta()), ), Entry("extended out of range (upper); extended expected in range (upper)", func(datum *extended.Extended) { datum.Extended = pointer.FromFloat64(250.1) datum.ExtendedExpected = pointer.FromFloat64(extended.ExtendedMaximum) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, extended.ExtendedMinimum, extended.ExtendedMaximum), "/extended", NewMeta()), ), Entry("extended out of range (upper); extended expected out of range (upper)", func(datum *extended.Extended) { datum.Extended = pointer.FromFloat64(250.1) datum.ExtendedExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, extended.ExtendedMaximum), "/extended", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, extended.ExtendedMinimum, extended.ExtendedMaximum), "/extended", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, extended.ExtendedMinimum, extended.ExtendedMaximum), "/expectedExtended", NewMeta()), ), Entry("duration missing; extended expected missing", @@ -471,14 +463,14 @@ var _ = Describe("Extended", func() { ), Entry("duration exists; extended expected missing", func(datum *extended.Extended) { - datum.DurationExpected = pointer.FromInt(86400000) + datum.DurationExpected = pointer.FromInt(extended.DurationMaximum) datum.ExtendedExpected = nil }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueExists(), "/expectedDuration", NewMeta()), ), Entry("duration exists; extended expected exists", func(datum *extended.Extended) { - datum.DurationExpected = pointer.FromInt(86400000) + datum.DurationExpected = pointer.FromInt(extended.DurationMaximum) datum.ExtendedExpected = pointer.FromFloat64(extended.ExtendedMaximum) }, ), @@ -494,9 +486,9 @@ var _ = Describe("Extended", func() { errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidType", "bolus"), "/type", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidSubType", "square"), "/subType", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/expectedDuration", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, extended.DurationMaximum), "/expectedDuration", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/extended", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0, extended.ExtendedMaximum), "/expectedExtended", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, extended.ExtendedMinimum, extended.ExtendedMaximum), "/expectedExtended", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), ), ) }) diff --git a/data/types/bolus/normal/normal.go b/data/types/bolus/normal/normal.go index f2d9775aaf..c387e54794 100644 --- a/data/types/bolus/normal/normal.go +++ b/data/types/bolus/normal/normal.go @@ -51,9 +51,6 @@ func (n *Normal) Validate(validator structure.Validator) { validator.Float64("normal", n.Normal).Exists().InRange(NormalMinimum, NormalMaximum) normalExpectedValidator := validator.Float64("expectedNormal", n.NormalExpected) if n.Normal != nil && *n.Normal >= NormalMinimum && *n.Normal <= NormalMaximum { - if *n.Normal == NormalMinimum { - normalExpectedValidator.Exists() - } normalExpectedValidator.InRange(*n.Normal, NormalMaximum) } else { normalExpectedValidator.InRange(NormalMinimum, NormalMaximum) diff --git a/data/types/bolus/normal/normal_test.go b/data/types/bolus/normal/normal_test.go index b73817050e..6d5f433dc6 100644 --- a/data/types/bolus/normal/normal_test.go +++ b/data/types/bolus/normal/normal_test.go @@ -96,7 +96,7 @@ var _ = Describe("Normal", func() { datum.NormalExpected = pointer.FromFloat64(-0.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, normal.NormalMaximum), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, normal.NormalMinimum, normal.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal missing; normal expected in range (lower)", func(datum *normal.Normal) { @@ -118,58 +118,51 @@ var _ = Describe("Normal", func() { datum.NormalExpected = pointer.FromFloat64(250.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, normal.NormalMinimum, normal.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal out of range (lower); normal expected missing", func(datum *normal.Normal) { datum.Normal = pointer.FromFloat64(-0.1) datum.NormalExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, normal.NormalMinimum, normal.NormalMaximum), "/normal", NewMeta()), ), Entry("normal out of range (lower); normal expected out of range (lower)", func(datum *normal.Normal) { datum.Normal = pointer.FromFloat64(-0.1) datum.NormalExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, normal.NormalMaximum), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, normal.NormalMinimum, normal.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, normal.NormalMinimum, normal.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal out of range (lower); normal expected in range (lower)", func(datum *normal.Normal) { datum.Normal = pointer.FromFloat64(-0.1) datum.NormalExpected = pointer.FromFloat64(0.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, normal.NormalMinimum, normal.NormalMaximum), "/normal", NewMeta()), ), Entry("normal out of range (lower); normal expected in range (upper)", func(datum *normal.Normal) { datum.Normal = pointer.FromFloat64(-0.1) datum.NormalExpected = pointer.FromFloat64(normal.NormalMaximum) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, normal.NormalMinimum, normal.NormalMaximum), "/normal", NewMeta()), ), Entry("normal out of range (lower); normal expected out of range (upper)", func(datum *normal.Normal) { datum.Normal = pointer.FromFloat64(-0.1) datum.NormalExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/expectedNormal", NewMeta()), - ), - Entry("normal in range (lower); normal expected missing", - func(datum *normal.Normal) { - datum.Normal = pointer.FromFloat64(0.0) - datum.NormalExpected = nil - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, normal.NormalMinimum, normal.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, normal.NormalMinimum, normal.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal in range (lower); normal expected out of range (lower)", func(datum *normal.Normal) { datum.Normal = pointer.FromFloat64(0.0) datum.NormalExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, normal.NormalMaximum), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, normal.NormalMinimum, normal.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal in range (lower); normal expected in range (lower)", func(datum *normal.Normal) { @@ -188,7 +181,7 @@ var _ = Describe("Normal", func() { datum.Normal = pointer.FromFloat64(0.0) datum.NormalExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, normal.NormalMinimum, normal.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal in range (upper); normal expected missing", func(datum *normal.Normal) { @@ -227,37 +220,37 @@ var _ = Describe("Normal", func() { datum.Normal = pointer.FromFloat64(250.1) datum.NormalExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, normal.NormalMinimum, normal.NormalMaximum), "/normal", NewMeta()), ), Entry("normal out of range (upper); normal expected out of range (lower)", func(datum *normal.Normal) { datum.Normal = pointer.FromFloat64(250.1) datum.NormalExpected = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, normal.NormalMaximum), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, normal.NormalMinimum, normal.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, normal.NormalMinimum, normal.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("normal out of range (upper); normal expected in range (lower)", func(datum *normal.Normal) { datum.Normal = pointer.FromFloat64(250.1) datum.NormalExpected = pointer.FromFloat64(0.0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, normal.NormalMinimum, normal.NormalMaximum), "/normal", NewMeta()), ), Entry("normal out of range (upper); normal expected in range (upper)", func(datum *normal.Normal) { datum.Normal = pointer.FromFloat64(250.1) datum.NormalExpected = pointer.FromFloat64(normal.NormalMaximum) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, normal.NormalMinimum, normal.NormalMaximum), "/normal", NewMeta()), ), Entry("normal out of range (upper); normal expected out of range (upper)", func(datum *normal.Normal) { datum.Normal = pointer.FromFloat64(250.1) datum.NormalExpected = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/normal", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/expectedNormal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, normal.NormalMinimum, normal.NormalMaximum), "/normal", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, normal.NormalMinimum, normal.NormalMaximum), "/expectedNormal", NewMeta()), ), Entry("multiple errors", func(datum *normal.Normal) { @@ -269,7 +262,7 @@ var _ = Describe("Normal", func() { errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidType", "bolus"), "/type", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidSubType", "normal"), "/subType", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/normal", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, normal.NormalMaximum), "/expectedNormal", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, normal.NormalMinimum, normal.NormalMaximum), "/expectedNormal", &bolus.Meta{Type: "invalidType", SubType: "invalidSubType"}), ), ) }) diff --git a/data/types/calculator/calculator.go b/data/types/calculator/calculator.go index 4a5d9e2585..f400b724e3 100644 --- a/data/types/calculator/calculator.go +++ b/data/types/calculator/calculator.go @@ -17,7 +17,7 @@ const ( CarbohydrateInputMaximum = 1000.0 CarbohydrateInputMinimum = 0.0 - InsulinCarbohydrateRatioMaximum = 250.0 + InsulinCarbohydrateRatioMaximum = 500.0 InsulinCarbohydrateRatioMinimum = 0.0 InsulinOnBoardMaximum = 250.0 InsulinOnBoardMinimum = 0.0 diff --git a/data/types/calculator/calculator_test.go b/data/types/calculator/calculator_test.go index 54b37bbba5..861de9c158 100644 --- a/data/types/calculator/calculator_test.go +++ b/data/types/calculator/calculator_test.go @@ -122,7 +122,7 @@ var _ = Describe("Calculator", func() { }) It("InsulinCarbohydrateRatioMaximum is expected", func() { - Expect(calculator.InsulinCarbohydrateRatioMaximum).To(Equal(250.0)) + Expect(calculator.InsulinCarbohydrateRatioMaximum).To(Equal(500.0)) }) It("InsulinCarbohydrateRatioMinimum is expected", func() { @@ -310,7 +310,7 @@ var _ = Describe("Calculator", func() { func(datum *calculator.Calculator, units *string) { datum.InsulinCarbohydrateRatio = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/insulinCarbRatio", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, calculator.InsulinCarbohydrateRatioMaximum), "/insulinCarbRatio", NewMeta()), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/units", NewMeta()), ), Entry("units missing; insulin carbohydrate ratio in range (lower)", @@ -323,16 +323,16 @@ var _ = Describe("Calculator", func() { Entry("units missing; insulin carbohydrate ratio in range (upper)", nil, func(datum *calculator.Calculator, units *string) { - datum.InsulinCarbohydrateRatio = pointer.FromFloat64(250.0) + datum.InsulinCarbohydrateRatio = pointer.FromFloat64(calculator.InsulinCarbohydrateRatioMaximum) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/units", NewMeta()), ), Entry("units missing; insulin carbohydrate ratio out of range (upper)", nil, func(datum *calculator.Calculator, units *string) { - datum.InsulinCarbohydrateRatio = pointer.FromFloat64(250.1) + datum.InsulinCarbohydrateRatio = pointer.FromFloat64(calculator.InsulinCarbohydrateRatioMaximum + 0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/insulinCarbRatio", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(calculator.InsulinCarbohydrateRatioMaximum+0.1, 0.0, calculator.InsulinCarbohydrateRatioMaximum), "/insulinCarbRatio", NewMeta()), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/units", NewMeta()), ), Entry("units missing; insulin on board missing", @@ -511,7 +511,7 @@ var _ = Describe("Calculator", func() { func(datum *calculator.Calculator, units *string) { datum.InsulinCarbohydrateRatio = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/insulinCarbRatio", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, calculator.InsulinCarbohydrateRatioMaximum), "/insulinCarbRatio", NewMeta()), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"mmol/L", "mmol/l", "mg/dL", "mg/dl"}), "/units", NewMeta()), ), Entry("units invalid; insulin carbohydrate ratio in range (lower)", @@ -524,16 +524,16 @@ var _ = Describe("Calculator", func() { Entry("units invalid; insulin carbohydrate ratio in range (upper)", pointer.FromString("invalid"), func(datum *calculator.Calculator, units *string) { - datum.InsulinCarbohydrateRatio = pointer.FromFloat64(250.0) + datum.InsulinCarbohydrateRatio = pointer.FromFloat64(calculator.InsulinCarbohydrateRatioMaximum) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"mmol/L", "mmol/l", "mg/dL", "mg/dl"}), "/units", NewMeta()), ), Entry("units invalid; insulin carbohydrate ratio out of range (upper)", pointer.FromString("invalid"), func(datum *calculator.Calculator, units *string) { - datum.InsulinCarbohydrateRatio = pointer.FromFloat64(250.1) + datum.InsulinCarbohydrateRatio = pointer.FromFloat64(calculator.InsulinCarbohydrateRatioMaximum + 0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/insulinCarbRatio", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(calculator.InsulinCarbohydrateRatioMaximum+0.1, 0.0, calculator.InsulinCarbohydrateRatioMaximum), "/insulinCarbRatio", NewMeta()), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"mmol/L", "mmol/l", "mg/dL", "mg/dl"}), "/units", NewMeta()), ), Entry("units invalid; insulin on board missing", @@ -694,7 +694,7 @@ var _ = Describe("Calculator", func() { func(datum *calculator.Calculator, units *string) { datum.InsulinCarbohydrateRatio = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/insulinCarbRatio", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, calculator.InsulinCarbohydrateRatioMaximum), "/insulinCarbRatio", NewMeta()), ), Entry("units mmol/L; insulin carbohydrate ratio in range (lower)", pointer.FromString("mmol/L"), @@ -705,15 +705,15 @@ var _ = Describe("Calculator", func() { Entry("units mmol/L; insulin carbohydrate ratio in range (upper)", pointer.FromString("mmol/L"), func(datum *calculator.Calculator, units *string) { - datum.InsulinCarbohydrateRatio = pointer.FromFloat64(250.0) + datum.InsulinCarbohydrateRatio = pointer.FromFloat64(calculator.InsulinCarbohydrateRatioMaximum) }, ), Entry("units mmol/L; insulin carbohydrate ratio out of range (upper)", pointer.FromString("mmol/L"), func(datum *calculator.Calculator, units *string) { - datum.InsulinCarbohydrateRatio = pointer.FromFloat64(250.1) + datum.InsulinCarbohydrateRatio = pointer.FromFloat64(calculator.InsulinCarbohydrateRatioMaximum + 0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/insulinCarbRatio", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(calculator.InsulinCarbohydrateRatioMaximum+0.1, 0.0, calculator.InsulinCarbohydrateRatioMaximum), "/insulinCarbRatio", NewMeta()), ), Entry("units mmol/L; insulin on board missing", pointer.FromString("mmol/L"), @@ -862,7 +862,7 @@ var _ = Describe("Calculator", func() { func(datum *calculator.Calculator, units *string) { datum.InsulinCarbohydrateRatio = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/insulinCarbRatio", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, calculator.InsulinCarbohydrateRatioMaximum), "/insulinCarbRatio", NewMeta()), ), Entry("units mmol/l; insulin carbohydrate ratio in range (lower)", pointer.FromString("mmol/l"), @@ -873,15 +873,15 @@ var _ = Describe("Calculator", func() { Entry("units mmol/l; insulin carbohydrate ratio in range (upper)", pointer.FromString("mmol/l"), func(datum *calculator.Calculator, units *string) { - datum.InsulinCarbohydrateRatio = pointer.FromFloat64(250.0) + datum.InsulinCarbohydrateRatio = pointer.FromFloat64(calculator.InsulinCarbohydrateRatioMaximum) }, ), Entry("units mmol/l; insulin carbohydrate ratio out of range (upper)", pointer.FromString("mmol/l"), func(datum *calculator.Calculator, units *string) { - datum.InsulinCarbohydrateRatio = pointer.FromFloat64(250.1) + datum.InsulinCarbohydrateRatio = pointer.FromFloat64(calculator.InsulinCarbohydrateRatioMaximum + 0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/insulinCarbRatio", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(calculator.InsulinCarbohydrateRatioMaximum+0.1, 0.0, calculator.InsulinCarbohydrateRatioMaximum), "/insulinCarbRatio", NewMeta()), ), Entry("units mmol/l; insulin on board missing", pointer.FromString("mmol/l"), @@ -1034,7 +1034,7 @@ var _ = Describe("Calculator", func() { func(datum *calculator.Calculator, units *string) { datum.InsulinCarbohydrateRatio = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/insulinCarbRatio", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, calculator.InsulinCarbohydrateRatioMaximum), "/insulinCarbRatio", NewMeta()), ), Entry("units mg/dL; insulin carbohydrate ratio in range (lower)", pointer.FromString("mg/dL"), @@ -1045,15 +1045,15 @@ var _ = Describe("Calculator", func() { Entry("units mg/dL; insulin carbohydrate ratio in range (upper)", pointer.FromString("mg/dL"), func(datum *calculator.Calculator, units *string) { - datum.InsulinCarbohydrateRatio = pointer.FromFloat64(250.0) + datum.InsulinCarbohydrateRatio = pointer.FromFloat64(calculator.InsulinCarbohydrateRatioMaximum) }, ), Entry("units mg/dL; insulin carbohydrate ratio out of range (upper)", pointer.FromString("mg/dL"), func(datum *calculator.Calculator, units *string) { - datum.InsulinCarbohydrateRatio = pointer.FromFloat64(250.1) + datum.InsulinCarbohydrateRatio = pointer.FromFloat64(calculator.InsulinCarbohydrateRatioMaximum + 0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/insulinCarbRatio", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(calculator.InsulinCarbohydrateRatioMaximum+0.1, 0.0, calculator.InsulinCarbohydrateRatioMaximum), "/insulinCarbRatio", NewMeta()), ), Entry("units mg/dL; insulin on board missing", pointer.FromString("mg/dL"), @@ -1206,7 +1206,7 @@ var _ = Describe("Calculator", func() { func(datum *calculator.Calculator, units *string) { datum.InsulinCarbohydrateRatio = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 250.0), "/insulinCarbRatio", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, calculator.InsulinCarbohydrateRatioMaximum), "/insulinCarbRatio", NewMeta()), ), Entry("units mg/dl; insulin carbohydrate ratio in range (lower)", pointer.FromString("mg/dl"), @@ -1217,15 +1217,15 @@ var _ = Describe("Calculator", func() { Entry("units mg/dl; insulin carbohydrate ratio in range (upper)", pointer.FromString("mg/dl"), func(datum *calculator.Calculator, units *string) { - datum.InsulinCarbohydrateRatio = pointer.FromFloat64(250.0) + datum.InsulinCarbohydrateRatio = pointer.FromFloat64(calculator.InsulinCarbohydrateRatioMaximum) }, ), Entry("units mg/dl; insulin carbohydrate ratio out of range (upper)", pointer.FromString("mg/dl"), func(datum *calculator.Calculator, units *string) { - datum.InsulinCarbohydrateRatio = pointer.FromFloat64(250.1) + datum.InsulinCarbohydrateRatio = pointer.FromFloat64(calculator.InsulinCarbohydrateRatioMaximum + 0.1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(250.1, 0.0, 250.0), "/insulinCarbRatio", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(calculator.InsulinCarbohydrateRatioMaximum+0.1, 0.0, calculator.InsulinCarbohydrateRatioMaximum), "/insulinCarbRatio", NewMeta()), ), Entry("units mg/dl; insulin on board missing", pointer.FromString("mg/dl"), diff --git a/data/types/calculator/recommended.go b/data/types/calculator/recommended.go index 64908c00be..9fbd9821bb 100644 --- a/data/types/calculator/recommended.go +++ b/data/types/calculator/recommended.go @@ -6,7 +6,7 @@ import ( ) const ( - CarbohydrateMaximum = 250.0 + CarbohydrateMaximum = 500.0 CarbohydrateMinimum = 0.0 CorrectionMaximum = 250.0 CorrectionMinimum = -250.0 diff --git a/data/types/calculator/recommended_test.go b/data/types/calculator/recommended_test.go index 17eced5646..3733bb17f2 100644 --- a/data/types/calculator/recommended_test.go +++ b/data/types/calculator/recommended_test.go @@ -35,7 +35,7 @@ func CloneRecommended(datum *calculator.Recommended) *calculator.Recommended { var _ = Describe("Recommended", func() { It("CarbohydrateMaximum is expected", func() { - Expect(calculator.CarbohydrateMaximum).To(Equal(250.0)) + Expect(calculator.CarbohydrateMaximum).To(Equal(500.0)) }) It("CarbohydrateMinimum is expected", func() { @@ -88,7 +88,7 @@ var _ = Describe("Recommended", func() { ), Entry("carbohydrate out of range (lower)", func(datum *calculator.Recommended) { datum.Carbohydrate = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-0.1, 0, calculator.InsulinCarbohydrateRatioMaximum), "/carb"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-0.1, 0, calculator.CarbohydrateMaximum), "/carb"), ), Entry("carbohydrate in range (lower)", func(datum *calculator.Recommended) { datum.Carbohydrate = pointer.FromFloat64(0.0) }, @@ -97,8 +97,10 @@ var _ = Describe("Recommended", func() { func(datum *calculator.Recommended) { datum.Carbohydrate = pointer.FromFloat64(100.0) }, ), Entry("carbohydrate out of range (upper)", - func(datum *calculator.Recommended) { datum.Carbohydrate = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(250.1, 0, calculator.InsulinCarbohydrateRatioMaximum), "/carb"), + func(datum *calculator.Recommended) { + datum.Carbohydrate = pointer.FromFloat64(calculator.CarbohydrateMaximum + 0.1) + }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(calculator.CarbohydrateMaximum+0.1, 0, calculator.CarbohydrateMaximum), "/carb"), ), Entry("correction missing", func(datum *calculator.Recommended) { datum.Correction = nil }, diff --git a/data/types/settings/pump/carbohydrate_ratio_start.go b/data/types/settings/pump/carbohydrate_ratio_start.go index de832d8176..b14baf32e7 100644 --- a/data/types/settings/pump/carbohydrate_ratio_start.go +++ b/data/types/settings/pump/carbohydrate_ratio_start.go @@ -11,7 +11,7 @@ import ( ) const ( - CarbohydrateRatioStartAmountMaximum = 250.0 + CarbohydrateRatioStartAmountMaximum = 500.0 CarbohydrateRatioStartAmountMinimum = 0.0 CarbohydrateRatioStartStartMaximum = 86400000 CarbohydrateRatioStartStartMinimum = 0 diff --git a/data/types/settings/pump/carbohydrate_ratio_start_test.go b/data/types/settings/pump/carbohydrate_ratio_start_test.go index 9e6b0466d2..c6ec59a771 100644 --- a/data/types/settings/pump/carbohydrate_ratio_start_test.go +++ b/data/types/settings/pump/carbohydrate_ratio_start_test.go @@ -16,7 +16,7 @@ import ( var _ = Describe("CarbohydrateRatioStart", func() { It("CarbohydrateRatioStartAmountMaximum is expected", func() { - Expect(pump.CarbohydrateRatioStartAmountMaximum).To(Equal(250.0)) + Expect(pump.CarbohydrateRatioStartAmountMaximum).To(Equal(500.0)) }) It("CarbohydrateRatioStartAmountMinimum is expected", func() { @@ -62,17 +62,21 @@ var _ = Describe("CarbohydrateRatioStart", func() { ), Entry("amount out of range (lower)", func(datum *pump.CarbohydrateRatioStart) { datum.Amount = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-0.1, 0, 250), "/amount"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-0.1, 0, pump.CarbohydrateRatioStartAmountMaximum), "/amount"), ), Entry("amount in range (lower)", func(datum *pump.CarbohydrateRatioStart) { datum.Amount = pointer.FromFloat64(0.0) }, ), Entry("amount in range (upper)", - func(datum *pump.CarbohydrateRatioStart) { datum.Amount = pointer.FromFloat64(250.0) }, + func(datum *pump.CarbohydrateRatioStart) { + datum.Amount = pointer.FromFloat64(pump.CarbohydrateRatioStartAmountMaximum) + }, ), Entry("amount out of range (upper)", - func(datum *pump.CarbohydrateRatioStart) { datum.Amount = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(250.1, 0, 250), "/amount"), + func(datum *pump.CarbohydrateRatioStart) { + datum.Amount = pointer.FromFloat64(pump.CarbohydrateRatioStartAmountMaximum + 0.1) + }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(pump.CarbohydrateRatioStartAmountMaximum+0.1, 0, pump.CarbohydrateRatioStartAmountMaximum), "/amount"), ), Entry("start missing", func(datum *pump.CarbohydrateRatioStart) { datum.Start = nil }, From d52e9d6cd6311be8a88911ad47083e38d1e6475c Mon Sep 17 00:00:00 2001 From: Jamie Bate Date: Thu, 3 Oct 2024 13:02:19 +1300 Subject: [PATCH 399/413] remove correlation with expectedExtended and expectedDuration (#778) expectedExtended and expectedDuration will be seen as independent params and no correlation between the two for validation --- data/types/bolus/combination/combination.go | 6 +----- data/types/bolus/combination/combination_test.go | 2 -- data/types/bolus/extended/extended.go | 6 +----- data/types/bolus/extended/extended_test.go | 2 -- 4 files changed, 2 insertions(+), 14 deletions(-) diff --git a/data/types/bolus/combination/combination.go b/data/types/bolus/combination/combination.go index 40dd571c50..ec140fb452 100644 --- a/data/types/bolus/combination/combination.go +++ b/data/types/bolus/combination/combination.go @@ -67,11 +67,7 @@ func (c *Combination) Validate(validator structure.Validator) { } else { durationExpectedValidator.InRange(DurationMinimum, DurationMaximum) } - if c.ExtendedExpected != nil { - durationExpectedValidator.Exists() - } else { - durationExpectedValidator.NotExists() - } + validator.Float64("extended", c.Extended).Exists().InRange(ExtendedMinimum, ExtendedMaximum) extendedExpectedValidator := validator.Float64("expectedExtended", c.ExtendedExpected) if c.Extended != nil && *c.Extended >= ExtendedMinimum && *c.Extended <= ExtendedMaximum { diff --git a/data/types/bolus/combination/combination_test.go b/data/types/bolus/combination/combination_test.go index 7484f5f5e8..b352dcfef2 100644 --- a/data/types/bolus/combination/combination_test.go +++ b/data/types/bolus/combination/combination_test.go @@ -728,7 +728,6 @@ var _ = Describe("Combination", func() { datum.DurationExpected = nil datum.ExtendedExpected = pointer.FromFloat64(combination.ExtendedMaximum) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/expectedDuration", NewMeta()), ), Entry("duration exists; extended expected missing", func(datum *combination.Combination) { @@ -737,7 +736,6 @@ var _ = Describe("Combination", func() { datum.DurationExpected = pointer.FromInt(combination.DurationMaximum) datum.ExtendedExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueExists(), "/expectedDuration", NewMeta()), ), Entry("duration exists; extended expected exists", func(datum *combination.Combination) { diff --git a/data/types/bolus/extended/extended.go b/data/types/bolus/extended/extended.go index e7f438612f..25029aa347 100644 --- a/data/types/bolus/extended/extended.go +++ b/data/types/bolus/extended/extended.go @@ -61,11 +61,7 @@ func (e *Extended) Validate(validator structure.Validator) { } else { durationExpectedValidator.InRange(DurationMinimum, DurationMaximum) } - if e.ExtendedExpected != nil { - durationExpectedValidator.Exists() - } else { - durationExpectedValidator.NotExists() - } + validator.Float64("extended", e.Extended).Exists().InRange(ExtendedMinimum, ExtendedMaximum) extendedExpectedValidator := validator.Float64("expectedExtended", e.ExtendedExpected) if e.Extended != nil && *e.Extended >= ExtendedMinimum && *e.Extended <= ExtendedMaximum { diff --git a/data/types/bolus/extended/extended_test.go b/data/types/bolus/extended/extended_test.go index 25b944c55d..c7fc1b73f2 100644 --- a/data/types/bolus/extended/extended_test.go +++ b/data/types/bolus/extended/extended_test.go @@ -459,14 +459,12 @@ var _ = Describe("Extended", func() { datum.DurationExpected = nil datum.ExtendedExpected = pointer.FromFloat64(extended.ExtendedMaximum) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/expectedDuration", NewMeta()), ), Entry("duration exists; extended expected missing", func(datum *extended.Extended) { datum.DurationExpected = pointer.FromInt(extended.DurationMaximum) datum.ExtendedExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueExists(), "/expectedDuration", NewMeta()), ), Entry("duration exists; extended expected exists", func(datum *extended.Extended) { From 5d39959eddd43aa2909650a723881b00252fecb4 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 21 Oct 2024 13:58:30 +1300 Subject: [PATCH 400/413] review updates --- data/blood/glucose/test/glucose.go | 8 ++-- .../deduplicator/device_deactivate_hash.go | 27 +++++------ data/deduplicator/deduplicator/hash.go | 45 +++++++++++-------- data/deduplicator/deduplicator/hash_test.go | 2 +- 4 files changed, 43 insertions(+), 39 deletions(-) diff --git a/data/blood/glucose/test/glucose.go b/data/blood/glucose/test/glucose.go index 445155ae57..a877cd7b43 100644 --- a/data/blood/glucose/test/glucose.go +++ b/data/blood/glucose/test/glucose.go @@ -15,15 +15,15 @@ func RandomUnits() string { func ExpectRaw(raw *metadata.Metadata, expectedRaw *metadata.Metadata) { if expectedRaw != nil { gomega.Expect(raw).ToNot(gomega.BeNil()) - if expectedRaw.Get("units") == nil { + if units := expectedRaw.Get("units"); units == nil { gomega.Expect(raw.Get("units")).To(gomega.BeNil()) } else { - gomega.Expect(raw.Get("units")).To(gomega.Equal(expectedRaw.Get("units"))) + gomega.Expect(raw.Get("units")).To(gomega.Equal(units)) } - if expectedRaw.Get("value") == nil { + if value := expectedRaw.Get("value"); value == nil { gomega.Expect(raw.Get("value")).To(gomega.BeNil()) } else { - gomega.Expect(raw.Get("value")).To(gomega.Equal(expectedRaw.Get("value"))) + gomega.Expect(raw.Get("value")).To(gomega.Equal(value)) } } else { gomega.Expect(raw).To(gomega.BeNil()) diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index 7eb7f71bfd..d7f6ac1e7b 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -11,12 +11,10 @@ import ( "github.com/tidepool-org/platform/pointer" ) -type DeviceDeactivateHashVersion string - const ( - DeviceDeactivateHashVersionUnkown DeviceDeactivateHashVersion = "" - DeviceDeactivateHashVersionCurrent DeviceDeactivateHashVersion = "1.1.0" - DeviceDeactivateHashVersionLegacy DeviceDeactivateHashVersion = "0.0.0" + DeviceDeactivateHashVersionUnknown string = "" + DeviceDeactivateHashVersionCurrent string = "1.1.0" + DeviceDeactivateHashVersionLegacy string = "0.0.0" ) const DeviceDeactivateHashName = "org.tidepool.deduplicator.device.deactivate.hash" @@ -67,14 +65,12 @@ func NewDeviceDeactivateHash() (*DeviceDeactivateHash, error) { }, nil } -func getDeviceDeactivateHashVersion(dataSet *dataTypesUpload.Upload) DeviceDeactivateHashVersion { +func getDeduplicatorVersion(dataSet *dataTypesUpload.Upload) string { if dataSet.Deduplicator != nil { if dataSet.Deduplicator.Name != nil && dataSet.Deduplicator.Version != nil { if *dataSet.Deduplicator.Name == DeviceDeactivateHashName { - if *dataSet.Deduplicator.Version == string(DeviceDeactivateHashVersionLegacy) { - return DeviceDeactivateHashVersionLegacy - } else if *dataSet.Deduplicator.Version == string(DeviceDeactivateHashVersionCurrent) { - return DeviceDeactivateHashVersionCurrent + if *dataSet.Deduplicator.Version != "" { + return *dataSet.Deduplicator.Version } } } @@ -99,7 +95,7 @@ func getDeviceDeactivateHashVersion(dataSet *dataTypesUpload.Upload) DeviceDeact } } } - return DeviceDeactivateHashVersionUnkown + return DeviceDeactivateHashVersionUnknown } func (d *DeviceDeactivateHash) New(dataSet *dataTypesUpload.Upload) (bool, error) { @@ -115,7 +111,8 @@ func (d *DeviceDeactivateHash) New(dataSet *dataTypesUpload.Upload) (bool, error if dataSet.HasDeduplicatorName() { return d.Get(dataSet) } - return getDeviceDeactivateHashVersion(dataSet) != DeviceDeactivateHashVersionUnkown, nil + //if hash version is set retur true + return getDeduplicatorVersion(dataSet) != DeviceDeactivateHashVersionUnknown, nil } func (d *DeviceDeactivateHash) Get(dataSet *dataTypesUpload.Upload) (bool, error) { @@ -124,7 +121,7 @@ func (d *DeviceDeactivateHash) Get(dataSet *dataTypesUpload.Upload) (bool, error return false, errors.New("data set is missing") } - if getDeviceDeactivateHashVersion(dataSet) == DeviceDeactivateHashVersionLegacy { + if getDeduplicatorVersion(dataSet) == DeviceDeactivateHashVersionLegacy { return true, nil } @@ -150,7 +147,7 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore options := NewDefaultDeviceDeactivateHashOptions() - if getDeviceDeactivateHashVersion(dataSet) == DeviceDeactivateHashVersionLegacy { + if getDeduplicatorVersion(dataSet) == DeviceDeactivateHashVersionLegacy { filter := &data.DataSetFilter{IsLegacy: pointer.FromBool(true), DeviceID: dataSet.DeviceID} pagination := &page.Pagination{Page: 1, Size: 1} @@ -160,7 +157,7 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore } if len(uploads) != 0 { if uploads[0].LegacyGroupID != nil { - options = NewLegacyDeviceDeactivateHashOptions(*uploads[0].LegacyGroupID) + options = NewLegacyHashOptions(*uploads[0].LegacyGroupID) } } } diff --git a/data/deduplicator/deduplicator/hash.go b/data/deduplicator/deduplicator/hash.go index 5b70c0d2b8..f7be1849c0 100644 --- a/data/deduplicator/deduplicator/hash.go +++ b/data/deduplicator/deduplicator/hash.go @@ -13,40 +13,47 @@ import ( "github.com/tidepool-org/platform/pointer" ) -type deviceDeactivateHashOptions struct { - version DeviceDeactivateHashVersion - legacyGroupID *string +type HashOptions struct { + Version string + LegacyGroupID *string } -func NewLegacyDeviceDeactivateHashOptions(legacyGroupID string) deviceDeactivateHashOptions { - return deviceDeactivateHashOptions{ - version: DeviceDeactivateHashVersionLegacy, - legacyGroupID: &legacyGroupID, +func NewLegacyHashOptions(legacyGroupID string) HashOptions { + return HashOptions{ + Version: DeviceDeactivateHashVersionLegacy, + LegacyGroupID: &legacyGroupID, } } -func NewDefaultDeviceDeactivateHashOptions() deviceDeactivateHashOptions { - return deviceDeactivateHashOptions{ - version: DeviceDeactivateHashVersionCurrent, +func NewDefaultDeviceDeactivateHashOptions() HashOptions { + return HashOptions{ + Version: DeviceDeactivateHashVersionCurrent, } } -func (d deviceDeactivateHashOptions) ValidateLegacy() error { - if d.version == DeviceDeactivateHashVersionLegacy { - if d.legacyGroupID == nil || *d.legacyGroupID == "" { +func (d HashOptions) Validate() error { + + switch d.Version { + case DeviceDeactivateHashVersionLegacy: + if d.LegacyGroupID == nil || *d.LegacyGroupID == "" { return errors.New("missing required legacy groupId for the device deactive hash legacy version") } + case DeviceDeactivateHashVersionCurrent: + break + default: + return errors.Newf("missing valid version %s", d.Version) } return nil } -func AssignDataSetDataIdentityHashes(dataSetData data.Data, options deviceDeactivateHashOptions) error { +func AssignDataSetDataIdentityHashes(dataSetData data.Data, options HashOptions) error { + if err := options.Validate(); err != nil { + return err + } for _, dataSetDatum := range dataSetData { var hash string - if options.version == DeviceDeactivateHashVersionLegacy { - if err := options.ValidateLegacy(); err != nil { - return err - } + if options.Version == DeviceDeactivateHashVersionLegacy { + fields, err := dataSetDatum.LegacyIdentityFields() if err != nil { return errors.Wrapf(err, "unable to gather legacy identity fields for datum %T", dataSetDatum) @@ -56,7 +63,7 @@ func AssignDataSetDataIdentityHashes(dataSetData data.Data, options deviceDeacti if err != nil { return errors.Wrapf(err, "unable to generate legacy identity hash for datum %T", dataSetDatum) } - hash, err = GenerateLegacyIdentityHash([]string{hash, *options.legacyGroupID}) + hash, err = GenerateLegacyIdentityHash([]string{hash, *options.LegacyGroupID}) if err != nil { return errors.Wrapf(err, "unable to generate legacy identity hash with legacy groupID for datum %T", dataSetDatum) } diff --git a/data/deduplicator/deduplicator/hash_test.go b/data/deduplicator/deduplicator/hash_test.go index 908bdf7ec1..cf60c5a9db 100644 --- a/data/deduplicator/deduplicator/hash_test.go +++ b/data/deduplicator/deduplicator/hash_test.go @@ -22,7 +22,7 @@ var _ = Describe("Hash", func() { Context("AssignDataSetDataIdentityHashes", func() { var dataSetDataTest []*dataTest.Datum var dataSetData data.Data - legacyOpts := dataDeduplicatorDeduplicator.NewLegacyDeviceDeactivateHashOptions("legacy-group-id") + legacyOpts := dataDeduplicatorDeduplicator.NewLegacyHashOptions("legacy-group-id") defaultOpts := dataDeduplicatorDeduplicator.NewDefaultDeviceDeactivateHashOptions() BeforeEach(func() { From 8328218100a46515463922be3ae5a27290c481b9 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 21 Oct 2024 17:01:23 +1300 Subject: [PATCH 401/413] update to use IdentityFields(version string) ([]string, error) --- data/datum.go | 3 +-- .../deduplicator/device_deactivate_hash.go | 5 ++-- data/deduplicator/deduplicator/hash.go | 14 ++++------ data/deduplicator/deduplicator/hash_test.go | 24 ++++++++--------- data/test/datum.go | 23 ++++------------ data/types/activity/physical/physical.go | 4 +-- data/types/activity/physical/physical_test.go | 4 +-- data/types/basal/basal.go | 22 ++++++++-------- data/types/basal/basal_test.go | 14 +++++----- data/types/base.go | 14 ++++++++-- data/types/base_test.go | 22 ++++++++-------- data/types/blood/blood.go | 13 ++++------ data/types/blood/blood_test.go | 15 ++++++----- .../glucose/selfmonitored/selfmonitored.go | 26 +++++++++++-------- .../selfmonitored/selfmonitored_test.go | 18 ++++++------- data/types/bolus/bolus.go | 23 ++++++++-------- data/types/bolus/bolus_test.go | 14 +++++----- data/types/calculator/calculator.go | 4 +-- data/types/calculator/calculator_test.go | 6 ++--- data/types/device/device.go | 24 ++++++++--------- data/types/device/device_test.go | 15 ++++++----- data/types/food/food.go | 4 +-- data/types/food/food_test.go | 4 +-- data/types/insulin/insulin.go | 4 +-- data/types/insulin/insulin_test.go | 4 +-- data/types/settings/cgm/cgm.go | 16 +++++++----- data/types/settings/cgm/cgm_test.go | 4 +-- 27 files changed, 171 insertions(+), 172 deletions(-) diff --git a/data/datum.go b/data/datum.go index 8f7ed065a0..75a34c07de 100644 --- a/data/datum.go +++ b/data/datum.go @@ -15,8 +15,7 @@ type Datum interface { Validate(validator structure.Validator) Normalize(normalizer Normalizer) - IdentityFields() ([]string, error) - LegacyIdentityFields() ([]string, error) + IdentityFields(version string) ([]string, error) GetOrigin() *origin.Origin GetPayload() *metadata.Metadata diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index d7f6ac1e7b..fa205a93ee 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -5,6 +5,7 @@ import ( "github.com/tidepool-org/platform/data" dataStore "github.com/tidepool-org/platform/data/store" + "github.com/tidepool-org/platform/data/types" dataTypesUpload "github.com/tidepool-org/platform/data/types/upload" "github.com/tidepool-org/platform/errors" "github.com/tidepool-org/platform/page" @@ -13,8 +14,8 @@ import ( const ( DeviceDeactivateHashVersionUnknown string = "" - DeviceDeactivateHashVersionCurrent string = "1.1.0" - DeviceDeactivateHashVersionLegacy string = "0.0.0" + DeviceDeactivateHashVersionCurrent string = types.IdentityFieldsVersion + DeviceDeactivateHashVersionLegacy string = types.LegacyIdentityFieldsVersion ) const DeviceDeactivateHashName = "org.tidepool.deduplicator.device.deactivate.hash" diff --git a/data/deduplicator/deduplicator/hash.go b/data/deduplicator/deduplicator/hash.go index f7be1849c0..c9d5afeb35 100644 --- a/data/deduplicator/deduplicator/hash.go +++ b/data/deduplicator/deduplicator/hash.go @@ -52,13 +52,13 @@ func AssignDataSetDataIdentityHashes(dataSetData data.Data, options HashOptions) } for _, dataSetDatum := range dataSetData { var hash string - if options.Version == DeviceDeactivateHashVersionLegacy { - fields, err := dataSetDatum.LegacyIdentityFields() - if err != nil { - return errors.Wrapf(err, "unable to gather legacy identity fields for datum %T", dataSetDatum) - } + fields, err := dataSetDatum.IdentityFields(options.Version) + if err != nil { + return errors.Wrap(err, "unable to gather identity fields for datum") + } + if options.Version == DeviceDeactivateHashVersionLegacy { hash, err = GenerateLegacyIdentityHash(fields) if err != nil { return errors.Wrapf(err, "unable to generate legacy identity hash for datum %T", dataSetDatum) @@ -68,10 +68,6 @@ func AssignDataSetDataIdentityHashes(dataSetData data.Data, options HashOptions) return errors.Wrapf(err, "unable to generate legacy identity hash with legacy groupID for datum %T", dataSetDatum) } } else { - fields, err := dataSetDatum.IdentityFields() - if err != nil { - return errors.Wrap(err, "unable to gather identity fields for datum") - } hash, err = GenerateIdentityHash(fields) if err != nil { return errors.Wrap(err, "unable to generate identity hash for datum") diff --git a/data/deduplicator/deduplicator/hash_test.go b/data/deduplicator/deduplicator/hash_test.go index cf60c5a9db..6b212cc638 100644 --- a/data/deduplicator/deduplicator/hash_test.go +++ b/data/deduplicator/deduplicator/hash_test.go @@ -64,11 +64,11 @@ var _ = Describe("Hash", func() { }) It("returns an error when any datum returns an error getting legacy identity fields", func() { - dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} + dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[0].GetTypeOutputs = []string{} - dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: nil, Error: errors.New("test error")}} + dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: nil, Error: errors.New("test error")}} dataSetDataTest[1].GetTypeOutputs = []string{} - Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, legacyOpts)).To(MatchError("unable to gather legacy identity fields for datum *test.Datum; test error")) + Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, legacyOpts)).To(MatchError("unable to gather identity fields for datum; test error")) }) It("returns an error when any datum returns no identity fields", func() { @@ -78,9 +78,9 @@ var _ = Describe("Hash", func() { }) It("returns an error when any datum returns no legacy identity fields", func() { - dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} + dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[0].GetTypeOutputs = []string{} - dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: nil, Error: nil}} + dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: nil, Error: nil}} dataSetDataTest[1].GetTypeOutputs = []string{} Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, legacyOpts)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity fields are missing")) }) @@ -92,9 +92,9 @@ var _ = Describe("Hash", func() { }) It("returns an error when any datum returns empty legacy identity fields", func() { - dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} + dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[0].GetTypeOutputs = []string{} - dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{}, Error: nil}} + dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{}, Error: nil}} dataSetDataTest[1].GetTypeOutputs = []string{} Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, legacyOpts)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity fields are missing")) }) @@ -106,9 +106,9 @@ var _ = Describe("Hash", func() { }) It("returns an error when any datum returns any empty legacy identity fields", func() { - dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} + dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), dataTest.NewDeviceID()}, Error: nil}} dataSetDataTest[0].GetTypeOutputs = []string{} - dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{userTest.RandomID(), ""}, Error: nil}} + dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{userTest.RandomID(), ""}, Error: nil}} dataSetDataTest[1].GetTypeOutputs = []string{} Expect(dataDeduplicatorDeduplicator.AssignDataSetDataIdentityHashes(dataSetData, legacyOpts)).To(MatchError("unable to generate legacy identity hash for datum *test.Datum; identity field is empty")) }) @@ -134,11 +134,11 @@ var _ = Describe("Hash", func() { Context("with legacy identity fields", func() { BeforeEach(func() { - dataSetDataTest[0].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{"test", "0"}, Error: nil}} + dataSetDataTest[0].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{"test", "0"}, Error: nil}} dataSetDataTest[0].GetTypeOutputs = []string{} - dataSetDataTest[1].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{"test", "1"}, Error: nil}} + dataSetDataTest[1].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{"test", "1"}, Error: nil}} dataSetDataTest[1].GetTypeOutputs = []string{} - dataSetDataTest[2].LegacyIdentityFieldsOutputs = []dataTest.LegacyIdentityFieldsOutput{{LegacyIdentityFields: []string{"test", "2"}, Error: nil}} + dataSetDataTest[2].IdentityFieldsOutputs = []dataTest.IdentityFieldsOutput{{IdentityFields: []string{"test", "2"}, Error: nil}} dataSetDataTest[2].GetTypeOutputs = []string{} }) diff --git a/data/test/datum.go b/data/test/datum.go index 7f3362a5bb..c5744946d1 100644 --- a/data/test/datum.go +++ b/data/test/datum.go @@ -6,6 +6,7 @@ import ( "github.com/onsi/gomega" "github.com/tidepool-org/platform/data" + "github.com/tidepool-org/platform/metadata" "github.com/tidepool-org/platform/origin" "github.com/tidepool-org/platform/structure" @@ -16,11 +17,6 @@ type IdentityFieldsOutput struct { Error error } -type LegacyIdentityFieldsOutput struct { - LegacyIdentityFields []string - Error error -} - type Datum struct { MetaInvocations int MetaOutputs []interface{} @@ -31,9 +27,8 @@ type Datum struct { NormalizeInvocations int NormalizeInputs []data.Normalizer IdentityFieldsInvocations int + IdentityFieldsInputs []string IdentityFieldsOutputs []IdentityFieldsOutput - LegacyIdentityFieldsInvocations int - LegacyIdentityFieldsOutputs []LegacyIdentityFieldsOutput GetPayloadInvocations int GetPayloadOutputs []*metadata.Metadata GetOriginInvocations int @@ -109,24 +104,16 @@ func (d *Datum) Normalize(normalizer data.Normalizer) { d.NormalizeInputs = append(d.NormalizeInputs, normalizer) } -func (d *Datum) IdentityFields() ([]string, error) { +func (d *Datum) IdentityFields(version string) ([]string, error) { d.IdentityFieldsInvocations++ + d.IdentityFieldsInputs = append(d.IdentityFieldsInputs, version) gomega.Expect(d.IdentityFieldsOutputs).ToNot(gomega.BeEmpty()) output := d.IdentityFieldsOutputs[0] d.IdentityFieldsOutputs = d.IdentityFieldsOutputs[1:] - return output.IdentityFields, output.Error -} - -func (d *Datum) LegacyIdentityFields() ([]string, error) { - d.LegacyIdentityFieldsInvocations++ - gomega.Expect(d.LegacyIdentityFieldsOutputs).ToNot(gomega.BeEmpty()) - - output := d.LegacyIdentityFieldsOutputs[0] - d.LegacyIdentityFieldsOutputs = d.LegacyIdentityFieldsOutputs[1:] - return output.LegacyIdentityFields, output.Error + return output.IdentityFields, output.Error } func (d *Datum) GetPayload() *metadata.Metadata { diff --git a/data/types/activity/physical/physical.go b/data/types/activity/physical/physical.go index 4e84ce24ee..db1f9717ca 100644 --- a/data/types/activity/physical/physical.go +++ b/data/types/activity/physical/physical.go @@ -297,6 +297,6 @@ func (p *Physical) Normalize(normalizer data.Normalizer) { } } -func (p *Physical) LegacyIdentityFields() ([]string, error) { - return p.Base.LegacyIdentityFields() +func (p *Physical) IdentityFields(version string) ([]string, error) { + return p.Base.IdentityFields(version) } diff --git a/data/types/activity/physical/physical_test.go b/data/types/activity/physical/physical_test.go index 5064bc9ca4..cbec0ab916 100644 --- a/data/types/activity/physical/physical_test.go +++ b/data/types/activity/physical/physical_test.go @@ -1365,14 +1365,14 @@ var _ = Describe("Physical", func() { ) }) - Context("LegacyIdentityFields", func() { + Context("Legacy IdentityFields", func() { It("returns the expected legacy identity fields", func() { datum := NewPhysical() datum.DeviceID = pointer.FromString("some-device") t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") Expect(err).ToNot(HaveOccurred()) datum.Time = pointer.FromTime(t) - legacyIdentityFields, err := datum.LegacyIdentityFields() + legacyIdentityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err).ToNot(HaveOccurred()) Expect(legacyIdentityFields).To(Equal([]string{"physicalActivity", "some-device", "2023-05-13T15:51:58.000Z"})) }) diff --git a/data/types/basal/basal.go b/data/types/basal/basal.go index aae4f04ae5..fc5ecc47b0 100644 --- a/data/types/basal/basal.go +++ b/data/types/basal/basal.go @@ -50,8 +50,17 @@ func (b *Basal) Validate(validator structure.Validator) { validator.String("deliveryType", &b.DeliveryType).Exists().NotEmpty() } -func (b *Basal) IdentityFields() ([]string, error) { - identityFields, err := b.Base.IdentityFields() +func (b *Basal) IdentityFields(version string) ([]string, error) { + if version == types.LegacyIdentityFieldsVersion { + return types.GetLegacyIDFields( + types.LegacyIDField{Name: "type", Value: &b.Type}, + types.LegacyIDField{Name: "delivery type", Value: &b.DeliveryType}, + types.LegacyIDField{Name: "device id", Value: b.DeviceID}, + types.GetLegacyTimeField(b.Time), + ) + } + + identityFields, err := b.Base.IdentityFields(version) if err != nil { return nil, err } @@ -63,15 +72,6 @@ func (b *Basal) IdentityFields() ([]string, error) { return append(identityFields, b.DeliveryType), nil } -func (b *Basal) LegacyIdentityFields() ([]string, error) { - return types.GetLegacyIDFields( - types.LegacyIDField{Name: "type", Value: &b.Type}, - types.LegacyIDField{Name: "delivery type", Value: &b.DeliveryType}, - types.LegacyIDField{Name: "device id", Value: b.DeviceID}, - types.GetLegacyTimeField(b.Time), - ) -} - func ParseDeliveryType(parser structure.ObjectParser) *string { if !parser.Exists() { return nil diff --git a/data/types/basal/basal_test.go b/data/types/basal/basal_test.go index a43f36ff74..53d662b7da 100644 --- a/data/types/basal/basal_test.go +++ b/data/types/basal/basal_test.go @@ -101,32 +101,32 @@ var _ = Describe("Basal", func() { It("returns error if user id is missing", func() { datum.UserID = nil - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(types.IdentityFieldsVersion) Expect(err).To(MatchError("user id is missing")) Expect(identityFields).To(BeEmpty()) }) It("returns error if user id is empty", func() { datum.UserID = pointer.FromString("") - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(types.IdentityFieldsVersion) Expect(err).To(MatchError("user id is empty")) Expect(identityFields).To(BeEmpty()) }) It("returns error if delivery type is empty", func() { datum.DeliveryType = "" - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(types.IdentityFieldsVersion) Expect(err).To(MatchError("delivery type is empty")) Expect(identityFields).To(BeEmpty()) }) It("returns the expected identity fields", func() { - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(types.IdentityFieldsVersion) Expect(err).ToNot(HaveOccurred()) Expect(identityFields).To(Equal([]string{*datum.UserID, *datum.DeviceID, (*datum.Time).Format(ExpectedTimeFormat), datum.Type, datum.DeliveryType})) }) }) - Context("LegacyIdentityFields", func() { + Context("Legacy IdentityFields", func() { var datum *basal.Basal BeforeEach(func() { @@ -135,7 +135,7 @@ var _ = Describe("Basal", func() { It("returns error if delivery type is empty", func() { datum.DeliveryType = "" - identityFields, err := datum.LegacyIdentityFields() + identityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err).To(MatchError("delivery type is empty")) Expect(identityFields).To(BeEmpty()) }) @@ -146,7 +146,7 @@ var _ = Describe("Basal", func() { Expect(err).ToNot(HaveOccurred()) datum.Time = pointer.FromTime(t) datum.DeliveryType = "some-delivery" - legacyIdentityFields, err := datum.LegacyIdentityFields() + legacyIdentityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err).ToNot(HaveOccurred()) Expect(legacyIdentityFields).To(Equal([]string{"basal", "some-delivery", "some-device", "2023-05-13T15:51:58.000Z"})) }) diff --git a/data/types/base.go b/data/types/base.go index bf5383e698..d35a67a767 100644 --- a/data/types/base.go +++ b/data/types/base.go @@ -30,6 +30,9 @@ const ( TimeZoneOffsetMaximum = 7 * 24 * 60 // TODO: Fix! Limit to reasonable values TimeZoneOffsetMinimum = -7 * 24 * 60 // TODO: Fix! Limit to reasonable values VersionInternalMinimum = 0 + + LegacyIdentityFieldsVersion = "0.0.0" + IdentityFieldsVersion = "1.1.0" ) type Base struct { @@ -239,7 +242,7 @@ func (b *Base) Normalize(normalizer data.Normalizer) { } } -func (b *Base) IdentityFields() ([]string, error) { +func currentIdentityFields(b *Base) ([]string, error) { if b.UserID == nil { return nil, errors.New("user id is missing") } @@ -265,6 +268,13 @@ func (b *Base) IdentityFields() ([]string, error) { return []string{*b.UserID, *b.DeviceID, (*b.Time).Format(TimeFormat), b.Type}, nil } +func (b *Base) IdentityFields(version string) ([]string, error) { + if version == LegacyIdentityFieldsVersion { + return legacyIdentityFields(b) + } + return currentIdentityFields(b) +} + type LegacyIDField struct { Value *string Name string @@ -297,7 +307,7 @@ func GetLegacyIDFields(fields ...LegacyIDField) ([]string, error) { return identityFields, nil } -func (b *Base) LegacyIdentityFields() ([]string, error) { +func legacyIdentityFields(b *Base) ([]string, error) { if b.Type == "" { return nil, errors.New("type is empty") } diff --git a/data/types/base_test.go b/data/types/base_test.go index 4f951856a0..9b575d0b18 100644 --- a/data/types/base_test.go +++ b/data/types/base_test.go @@ -912,6 +912,7 @@ var _ = Describe("Base", func() { Context("with new, initialized datum", func() { var datum *types.Base + const currentVersion = "1.1.0" BeforeEach(func() { datum = dataTypesTest.RandomBase() @@ -920,62 +921,61 @@ var _ = Describe("Base", func() { Context("IdentityFields", func() { It("returns error if user id is missing", func() { datum.UserID = nil - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(currentVersion) Expect(err).To(MatchError("user id is missing")) Expect(identityFields).To(BeEmpty()) }) It("returns error if user id is empty", func() { datum.UserID = pointer.FromString("") - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(currentVersion) Expect(err).To(MatchError("user id is empty")) Expect(identityFields).To(BeEmpty()) }) It("returns error if device id is missing", func() { datum.DeviceID = nil - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(currentVersion) Expect(err).To(MatchError("device id is missing")) Expect(identityFields).To(BeEmpty()) }) It("returns error if device id is empty", func() { datum.DeviceID = pointer.FromString("") - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(currentVersion) Expect(err).To(MatchError("device id is empty")) Expect(identityFields).To(BeEmpty()) }) It("returns error if time is missing", func() { datum.Time = nil - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(currentVersion) Expect(err).To(MatchError("time is missing")) Expect(identityFields).To(BeEmpty()) }) It("returns error if time is empty", func() { datum.Time = pointer.FromTime(time.Time{}) - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(currentVersion) Expect(err).To(MatchError("time is empty")) Expect(identityFields).To(BeEmpty()) }) It("returns error if type is empty", func() { datum.Type = "" - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(currentVersion) Expect(err).To(MatchError("type is empty")) Expect(identityFields).To(BeEmpty()) }) It("returns the expected identity fields", func() { - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(currentVersion) Expect(err).ToNot(HaveOccurred()) Expect(identityFields).To(Equal([]string{*datum.UserID, *datum.DeviceID, (*datum.Time).Format(ExpectedTimeFormat), datum.Type})) }) }) - Context("LegacyIdentityFields", func() { - + Context("Legacy IdentityFields", func() { var datum *types.Base BeforeEach(func() { @@ -983,7 +983,7 @@ var _ = Describe("Base", func() { }) It("returns the expected empty identity fields", func() { - legacyIDFields, err := datum.LegacyIdentityFields() + legacyIDFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err).To(BeNil()) Expect(legacyIDFields).ToNot(BeEmpty()) Expect(legacyIDFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyTimeFormat)})) diff --git a/data/types/blood/blood.go b/data/types/blood/blood.go index 29a9b358ff..94ff9a74b9 100644 --- a/data/types/blood/blood.go +++ b/data/types/blood/blood.go @@ -30,26 +30,23 @@ func (b *Blood) Parse(parser structure.ObjectParser) { b.Value = parser.Float64("value") } -func (b *Blood) IdentityFields() ([]string, error) { - identityFields, err := b.Base.IdentityFields() +func (b *Blood) IdentityFields(version string) ([]string, error) { + if version == types.LegacyIdentityFieldsVersion { + return b.Base.IdentityFields(version) + } + identityFields, err := b.Base.IdentityFields(version) if err != nil { return nil, err } - if b.Units == nil { return nil, errors.New("units is missing") } if b.Value == nil { return nil, errors.New("value is missing") } - return append(identityFields, *b.Units, strconv.FormatFloat(*b.Value, 'f', -1, 64)), nil } -func (b *Blood) LegacyIdentityFields() ([]string, error) { - return b.Base.LegacyIdentityFields() -} - func (b *Blood) GetRawValueAndUnits() (*float64, *string, error) { if b.Raw == nil { return nil, nil, errors.New("raw data is missing") diff --git a/data/types/blood/blood_test.go b/data/types/blood/blood_test.go index 93363b22a6..02380606c8 100644 --- a/data/types/blood/blood_test.go +++ b/data/types/blood/blood_test.go @@ -89,6 +89,7 @@ var _ = Describe("Blood", func() { Context("IdentityFields", func() { var datum *blood.Blood + const currentVersion = "1.1.0" BeforeEach(func() { datum = dataTypesBloodTest.NewBlood() @@ -96,40 +97,40 @@ var _ = Describe("Blood", func() { It("returns error if user id is missing", func() { datum.UserID = nil - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(currentVersion) Expect(err).To(MatchError("user id is missing")) Expect(identityFields).To(BeEmpty()) }) It("returns error if user id is empty", func() { datum.UserID = pointer.FromString("") - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(currentVersion) Expect(err).To(MatchError("user id is empty")) Expect(identityFields).To(BeEmpty()) }) It("returns error if units is missing", func() { datum.Units = nil - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(currentVersion) Expect(err).To(MatchError("units is missing")) Expect(identityFields).To(BeEmpty()) }) It("returns error if value is missing", func() { datum.Value = nil - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(currentVersion) Expect(err).To(MatchError("value is missing")) Expect(identityFields).To(BeEmpty()) }) It("returns the expected identity fields", func() { - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(currentVersion) Expect(err).ToNot(HaveOccurred()) Expect(identityFields).To(Equal([]string{*datum.UserID, *datum.DeviceID, (*datum.Time).Format(ExpectedTimeFormat), datum.Type, *datum.Units, strconv.FormatFloat(*datum.Value, 'f', -1, 64)})) }) }) - Context("LegacyIdentityFields", func() { + Context("Legacy IdentityFields", func() { It("returns the expected legacy identity fields", func() { datum := dataTypesBloodTest.NewBlood() datum.Type = "bg" @@ -137,7 +138,7 @@ var _ = Describe("Blood", func() { t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") Expect(err).ToNot(HaveOccurred()) datum.Time = pointer.FromTime(t) - legacyIdentityFields, err := datum.LegacyIdentityFields() + legacyIdentityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err).ToNot(HaveOccurred()) Expect(legacyIdentityFields).To(Equal([]string{"bg", "some-bg-device", "2023-05-13T15:51:58.000Z"})) }) diff --git a/data/types/blood/glucose/selfmonitored/selfmonitored.go b/data/types/blood/glucose/selfmonitored/selfmonitored.go index 9faea94eed..c101d8097d 100644 --- a/data/types/blood/glucose/selfmonitored/selfmonitored.go +++ b/data/types/blood/glucose/selfmonitored/selfmonitored.go @@ -5,6 +5,7 @@ import ( "github.com/tidepool-org/platform/data" dataBloodGlucose "github.com/tidepool-org/platform/data/blood/glucose" + "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/data/types/blood/glucose" "github.com/tidepool-org/platform/structure" ) @@ -69,16 +70,19 @@ func (s *SelfMonitored) Normalize(normalizer data.Normalizer) { s.Glucose.Normalize(normalizer) } -func (s *SelfMonitored) LegacyIdentityFields() ([]string, error) { - identityFields, err := s.Blood.LegacyIdentityFields() - if err != nil { - return nil, err +func (s *SelfMonitored) IdentityFields(version string) ([]string, error) { + if version == types.LegacyIdentityFieldsVersion { + identityFields, err := s.Blood.IdentityFields(version) + if err != nil { + return nil, err + } + value, units, err := s.GetRawValueAndUnits() + if err != nil { + return nil, err + } + fullPrecisionValue := dataBloodGlucose.NormalizeValueForUnitsWithFullPrecision(value, units) + identityFields = append(identityFields, strconv.FormatFloat(*fullPrecisionValue, 'f', -1, 64)) + return identityFields, nil } - value, units, err := s.GetRawValueAndUnits() - if err != nil { - return nil, err - } - fullPrecisionValue := dataBloodGlucose.NormalizeValueForUnitsWithFullPrecision(value, units) - identityFields = append(identityFields, strconv.FormatFloat(*fullPrecisionValue, 'f', -1, 64)) - return identityFields, nil + return s.Blood.IdentityFields(version) } diff --git a/data/types/blood/glucose/selfmonitored/selfmonitored_test.go b/data/types/blood/glucose/selfmonitored/selfmonitored_test.go index bd33486c3c..61394fdf91 100644 --- a/data/types/blood/glucose/selfmonitored/selfmonitored_test.go +++ b/data/types/blood/glucose/selfmonitored/selfmonitored_test.go @@ -501,7 +501,7 @@ var _ = Describe("SelfMonitored", func() { ) }) - Context("LegacyIdentityFields", func() { + Context("Legacy IdentityFields", func() { var datum *selfmonitored.SelfMonitored BeforeEach(func() { @@ -513,49 +513,49 @@ var _ = Describe("SelfMonitored", func() { It("returns error if device id is missing", func() { datum.DeviceID = nil - identityFields, err := datum.LegacyIdentityFields() + identityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err).To(MatchError("device id is missing")) Expect(identityFields).To(BeEmpty()) }) It("returns error if device id is empty", func() { datum.DeviceID = pointer.FromString("") - identityFields, err := datum.LegacyIdentityFields() + identityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err).To(MatchError("device id is empty")) Expect(identityFields).To(BeEmpty()) }) It("returns error if time is missing", func() { datum.Time = nil - identityFields, err := datum.LegacyIdentityFields() + identityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err).To(MatchError("time is missing")) Expect(identityFields).To(BeEmpty()) }) It("returns error if time is empty", func() { datum.Time = &time.Time{} - identityFields, err := datum.LegacyIdentityFields() + identityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err).To(MatchError("time is empty")) Expect(identityFields).To(BeEmpty()) }) It("returns error if raw is missing", func() { datum.Raw = nil - identityFields, err := datum.LegacyIdentityFields() + identityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err.Error()).To(Equal("raw data is missing")) Expect(identityFields).To(BeEmpty()) }) It("returns error if raw value is missing", func() { datum.Raw.Delete("value") - identityFields, err := datum.LegacyIdentityFields() + identityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err.Error()).To(Equal("raw value is missing")) Expect(identityFields).To(BeEmpty()) }) It("returns error if raw units are missing", func() { datum.Raw.Delete("units") - identityFields, err := datum.LegacyIdentityFields() + identityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err.Error()).To(Equal("raw units are missing")) Expect(identityFields).To(BeEmpty()) }) @@ -569,7 +569,7 @@ var _ = Describe("SelfMonitored", func() { t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") Expect(err).ToNot(HaveOccurred()) datum.Time = pointer.FromTime(t) - legacyIdentityFields, err := datum.LegacyIdentityFields() + legacyIdentityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err).ToNot(HaveOccurred()) Expect(legacyIdentityFields).To(Equal([]string{"smbg", "some-device", "2023-05-13T15:51:58.000Z", "12.211645580300173"})) }) diff --git a/data/types/bolus/bolus.go b/data/types/bolus/bolus.go index 6a0d550b97..91d13863e8 100644 --- a/data/types/bolus/bolus.go +++ b/data/types/bolus/bolus.go @@ -81,8 +81,18 @@ func (b *Bolus) Normalize(normalizer data.Normalizer) { } } -func (b *Bolus) IdentityFields() ([]string, error) { - identityFields, err := b.Base.IdentityFields() +func (b *Bolus) IdentityFields(version string) ([]string, error) { + + if version == types.LegacyIdentityFieldsVersion { + return types.GetLegacyIDFields( + types.LegacyIDField{Name: "type", Value: &b.Type}, + types.LegacyIDField{Name: "sub type", Value: &b.SubType}, + types.LegacyIDField{Name: "device id", Value: b.DeviceID}, + types.GetLegacyTimeField(b.Time), + ) + } + + identityFields, err := b.Base.IdentityFields(version) if err != nil { return nil, err } @@ -93,12 +103,3 @@ func (b *Bolus) IdentityFields() ([]string, error) { return append(identityFields, b.SubType), nil } - -func (b *Bolus) LegacyIdentityFields() ([]string, error) { - return types.GetLegacyIDFields( - types.LegacyIDField{Name: "type", Value: &b.Type}, - types.LegacyIDField{Name: "sub type", Value: &b.SubType}, - types.LegacyIDField{Name: "device id", Value: b.DeviceID}, - types.GetLegacyTimeField(b.Time), - ) -} diff --git a/data/types/bolus/bolus_test.go b/data/types/bolus/bolus_test.go index 70052e11d6..d3fc4ade09 100644 --- a/data/types/bolus/bolus_test.go +++ b/data/types/bolus/bolus_test.go @@ -163,33 +163,33 @@ var _ = Describe("Bolus", func() { It("returns error if user id is missing", func() { datum.UserID = nil - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(types.IdentityFieldsVersion) Expect(err).To(MatchError("user id is missing")) Expect(identityFields).To(BeEmpty()) }) It("returns error if user id is empty", func() { datum.UserID = pointer.FromString("") - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(types.IdentityFieldsVersion) Expect(err).To(MatchError("user id is empty")) Expect(identityFields).To(BeEmpty()) }) It("returns error if sub type is empty", func() { datum.SubType = "" - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(types.IdentityFieldsVersion) Expect(err).To(MatchError("sub type is empty")) Expect(identityFields).To(BeEmpty()) }) It("returns the expected identity fields", func() { - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(types.IdentityFieldsVersion) Expect(err).ToNot(HaveOccurred()) Expect(identityFields).To(Equal([]string{*datum.UserID, *datum.DeviceID, (*datum.Time).Format(ExpectedTimeFormat), datum.Type, datum.SubType})) }) }) - Context("LegacyIdentityFields", func() { + Context("Legacy IdentityFields", func() { var datum *bolus.Bolus BeforeEach(func() { @@ -198,7 +198,7 @@ var _ = Describe("Bolus", func() { It("returns error if sub type is empty", func() { datum.SubType = "" - identityFields, err := datum.LegacyIdentityFields() + identityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err).To(MatchError("sub type is empty")) Expect(identityFields).To(BeEmpty()) }) @@ -209,7 +209,7 @@ var _ = Describe("Bolus", func() { Expect(err).ToNot(HaveOccurred()) datum.Time = pointer.FromTime(t) datum.SubType = "some-sub-type" - legacyIdentityFields, err := datum.LegacyIdentityFields() + legacyIdentityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err).ToNot(HaveOccurred()) Expect(legacyIdentityFields).To(Equal([]string{"bolus", "some-sub-type", "some-device", "2023-05-13T15:51:58.000Z"})) }) diff --git a/data/types/calculator/calculator.go b/data/types/calculator/calculator.go index f400b724e3..f469f0a98d 100644 --- a/data/types/calculator/calculator.go +++ b/data/types/calculator/calculator.go @@ -118,8 +118,8 @@ func (c *Calculator) Validate(validator structure.Validator) { } } -func (c *Calculator) LegacyIdentityFields() ([]string, error) { - return c.Base.LegacyIdentityFields() +func (c *Calculator) IdentityFields(version string) ([]string, error) { + return c.Base.IdentityFields(version) } func (c *Calculator) Normalize(normalizer data.Normalizer) { diff --git a/data/types/calculator/calculator_test.go b/data/types/calculator/calculator_test.go index 861de9c158..a11dab45cf 100644 --- a/data/types/calculator/calculator_test.go +++ b/data/types/calculator/calculator_test.go @@ -155,7 +155,7 @@ var _ = Describe("Calculator", func() { Expect(datum.CarbUnits).To(BeNil()) }) }) - Context("LegacyIdentityFields", func() { + Context("Legacy IdentityFields", func() { var datum *calculator.Calculator BeforeEach(func() { @@ -164,7 +164,7 @@ var _ = Describe("Calculator", func() { It("returns error if delivery type is empty", func() { datum.Type = "" - identityFields, err := datum.LegacyIdentityFields() + identityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err).To(MatchError("type is empty")) Expect(identityFields).To(BeEmpty()) }) @@ -174,7 +174,7 @@ var _ = Describe("Calculator", func() { t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") Expect(err).ToNot(HaveOccurred()) datum.Time = pointer.FromTime(t) - legacyIdentityFields, err := datum.LegacyIdentityFields() + legacyIdentityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err).ToNot(HaveOccurred()) Expect(legacyIdentityFields).To(Equal([]string{"wizard", "some-device", "2023-05-13T15:51:58.000Z"})) }) diff --git a/data/types/device/device.go b/data/types/device/device.go index 6dab185b2b..f48a80254b 100644 --- a/data/types/device/device.go +++ b/data/types/device/device.go @@ -45,24 +45,22 @@ func (d *Device) Validate(validator structure.Validator) { validator.String("subType", &d.SubType).Exists().NotEmpty() } -func (d *Device) IdentityFields() ([]string, error) { - identityFields, err := d.Base.IdentityFields() +func (d *Device) IdentityFields(version string) ([]string, error) { + if version == types.LegacyIdentityFieldsVersion { + return types.GetLegacyIDFields( + types.LegacyIDField{Name: "type", Value: &d.Type}, + types.LegacyIDField{Name: "sub type", Value: &d.SubType}, + types.GetLegacyTimeField(d.Time), + types.LegacyIDField{Name: "device id", Value: d.DeviceID}, + ) + } + + identityFields, err := d.Base.IdentityFields(version) if err != nil { return nil, err } - if d.SubType == "" { return nil, errors.New("sub type is empty") } - return append(identityFields, d.SubType), nil } - -func (d *Device) LegacyIdentityFields() ([]string, error) { - return types.GetLegacyIDFields( - types.LegacyIDField{Name: "type", Value: &d.Type}, - types.LegacyIDField{Name: "sub type", Value: &d.SubType}, - types.GetLegacyTimeField(d.Time), - types.LegacyIDField{Name: "device id", Value: d.DeviceID}, - ) -} diff --git a/data/types/device/device_test.go b/data/types/device/device_test.go index 521937dfba..57a7926ca0 100644 --- a/data/types/device/device_test.go +++ b/data/types/device/device_test.go @@ -94,6 +94,7 @@ var _ = Describe("Device", func() { Context("IdentityFields", func() { var datum *device.Device + const currentVersion = "1.1.0" BeforeEach(func() { datum = dataTypesDeviceTest.RandomDevice() @@ -101,33 +102,33 @@ var _ = Describe("Device", func() { It("returns error if user id is missing", func() { datum.UserID = nil - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(currentVersion) Expect(err).To(MatchError("user id is missing")) Expect(identityFields).To(BeEmpty()) }) It("returns error if user id is empty", func() { datum.UserID = pointer.FromString("") - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(currentVersion) Expect(err).To(MatchError("user id is empty")) Expect(identityFields).To(BeEmpty()) }) It("returns error if sub type is empty", func() { datum.SubType = "" - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(currentVersion) Expect(err).To(MatchError("sub type is empty")) Expect(identityFields).To(BeEmpty()) }) It("returns the expected identity fields", func() { - identityFields, err := datum.IdentityFields() + identityFields, err := datum.IdentityFields(currentVersion) Expect(err).ToNot(HaveOccurred()) Expect(identityFields).To(Equal([]string{*datum.UserID, *datum.DeviceID, (*datum.Time).Format(ExpectedTimeFormat), datum.Type, datum.SubType})) }) }) - Context("LegacyIdentityFields", func() { + Context("Legacy IdentityFields", func() { var datum *device.Device BeforeEach(func() { @@ -136,7 +137,7 @@ var _ = Describe("Device", func() { It("returns error if sub type is empty", func() { datum.SubType = "" - identityFields, err := datum.LegacyIdentityFields() + identityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err).To(MatchError("sub type is empty")) Expect(identityFields).To(BeEmpty()) }) @@ -147,7 +148,7 @@ var _ = Describe("Device", func() { Expect(err).ToNot(HaveOccurred()) datum.Time = pointer.FromTime(t) datum.SubType = "some-sub-type" - legacyIdentityFields, err := datum.LegacyIdentityFields() + legacyIdentityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err).ToNot(HaveOccurred()) Expect(legacyIdentityFields).To(Equal([]string{"deviceEvent", "some-sub-type", "2023-05-13T15:51:58.000Z", "some-device"})) }) diff --git a/data/types/food/food.go b/data/types/food/food.go index 26c47f18be..84bcdd485d 100644 --- a/data/types/food/food.go +++ b/data/types/food/food.go @@ -105,6 +105,6 @@ func (f *Food) Normalize(normalizer data.Normalizer) { f.Base.Normalize(normalizer) } -func (f *Food) LegacyIdentityFields() ([]string, error) { - return f.Base.LegacyIdentityFields() +func (f *Food) IdentityFields(version string) ([]string, error) { + return f.Base.IdentityFields(version) } diff --git a/data/types/food/food_test.go b/data/types/food/food_test.go index 2a634527a2..1e123d96c2 100644 --- a/data/types/food/food_test.go +++ b/data/types/food/food_test.go @@ -435,14 +435,14 @@ var _ = Describe("Food", func() { ) }) - Context("LegacyIdentityFields", func() { + Context("Legacy IdentityFields", func() { It("returns the expected legacy identity fields", func() { datum := dataTypesFoodTest.RandomFood(3) datum.DeviceID = pointer.FromString("some-device") t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") Expect(err).ToNot(HaveOccurred()) datum.Time = pointer.FromTime(t) - legacyIdentityFields, err := datum.LegacyIdentityFields() + legacyIdentityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err).ToNot(HaveOccurred()) Expect(legacyIdentityFields).To(Equal([]string{"food", "some-device", "2023-05-13T15:51:58.000Z"})) }) diff --git a/data/types/insulin/insulin.go b/data/types/insulin/insulin.go index 2a579db308..13afaae8f9 100644 --- a/data/types/insulin/insulin.go +++ b/data/types/insulin/insulin.go @@ -73,6 +73,6 @@ func (i *Insulin) Normalize(normalizer data.Normalizer) { } } -func (i *Insulin) LegacyIdentityFields() ([]string, error) { - return i.Base.LegacyIdentityFields() +func (i *Insulin) IdentityFields(version string) ([]string, error) { + return i.Base.IdentityFields(version) } diff --git a/data/types/insulin/insulin_test.go b/data/types/insulin/insulin_test.go index aa07e1da25..88aef5b77d 100644 --- a/data/types/insulin/insulin_test.go +++ b/data/types/insulin/insulin_test.go @@ -169,14 +169,14 @@ var _ = Describe("Insulin", func() { ) }) - Context("LegacyIdentityFields", func() { + Context("Legacy IdentityFields", func() { It("returns the expected legacy identity fields", func() { datum := NewInsulin() datum.DeviceID = pointer.FromString("some-pump-device") t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") Expect(err).ToNot(HaveOccurred()) datum.Time = pointer.FromTime(t) - legacyIdentityFields, err := datum.LegacyIdentityFields() + legacyIdentityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err).ToNot(HaveOccurred()) Expect(legacyIdentityFields).To(Equal([]string{"insulin", "some-pump-device", "2023-05-13T15:51:58.000Z"})) }) diff --git a/data/types/settings/cgm/cgm.go b/data/types/settings/cgm/cgm.go index 4ae7eab0f5..4049b2a150 100644 --- a/data/types/settings/cgm/cgm.go +++ b/data/types/settings/cgm/cgm.go @@ -6,6 +6,7 @@ import ( "github.com/tidepool-org/platform/data" dataBloodGlucose "github.com/tidepool-org/platform/data/blood/glucose" + "github.com/tidepool-org/platform/data/types" dataTypes "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/errors" "github.com/tidepool-org/platform/structure" @@ -156,12 +157,15 @@ func (c *CGM) Normalize(normalizer data.Normalizer) { } } -func (c *CGM) LegacyIdentityFields() ([]string, error) { - return dataTypes.GetLegacyIDFields( - dataTypes.LegacyIDField{Name: "type", Value: &c.Type}, - dataTypes.GetLegacyTimeField(c.Time), - dataTypes.LegacyIDField{Name: "device id", Value: c.DeviceID}, - ) +func (c *CGM) IdentityFields(version string) ([]string, error) { + if version == types.LegacyIdentityFieldsVersion { + return dataTypes.GetLegacyIDFields( + dataTypes.LegacyIDField{Name: "type", Value: &c.Type}, + dataTypes.GetLegacyTimeField(c.Time), + dataTypes.LegacyIDField{Name: "device id", Value: c.DeviceID}, + ) + } + return c.Base.IdentityFields(version) } func IsValidTransmitterID(value string) bool { diff --git a/data/types/settings/cgm/cgm_test.go b/data/types/settings/cgm/cgm_test.go index dc1830a8c4..683491b06f 100644 --- a/data/types/settings/cgm/cgm_test.go +++ b/data/types/settings/cgm/cgm_test.go @@ -597,14 +597,14 @@ var _ = Describe("CGM", func() { ) }) - Context("LegacyIdentityFields", func() { + Context("Legacy IdentityFields", func() { It("returns the expected legacy identity fields", func() { datum := dataTypesSettingsCgmTest.RandomCGM(pointer.FromString("mmol/l")) datum.DeviceID = pointer.FromString("some-cgm-device") t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") Expect(err).ToNot(HaveOccurred()) datum.Time = pointer.FromTime(t) - legacyIdentityFields, err := datum.LegacyIdentityFields() + legacyIdentityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) Expect(err).ToNot(HaveOccurred()) Expect(legacyIdentityFields).To(Equal([]string{"cgmSettings", "2023-05-13T15:51:58.000Z", "some-cgm-device"})) }) From f87f0483f50025c74b6304e7e8108eb258ff4884 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 22 Oct 2024 13:37:33 +1300 Subject: [PATCH 402/413] review updates --- data/data_set.go | 2 +- .../deduplicator/device_deactivate_hash.go | 2 +- data/service/service/standard.go | 2 +- data/store/mongo/mongo_data_set.go | 9 +- data/types/basal/suspend/suspend_test.go | 2 +- data/types/blood/blood.go | 4 + data/types/blood/glucose/glucose_test.go | 1 - .../selfmonitored/selfmonitored_test.go | 3 +- data/types/bolus/test/bolus.go | 7 +- data/types/calculator/recommended_test.go | 18 +-- data/types/common/day.go | 24 ++-- data/types/common/day_test.go | 5 +- data/types/device/device_test.go | 8 +- data/types/food/food_test.go | 5 +- data/types/settings/cgm/cgm_test.go | 5 +- .../pump/bolus_amount_maximum_test.go | 29 ++--- data/types/settings/pump/bolus_test.go | 3 +- data/types/settings/pump/pump_test.go | 8 +- data/types/settings/pump/sleep_schedule.go | 13 +- .../settings/pump/sleep_schedule_test.go | 122 +++++++++++------- data/types/settings/pump/test/bolus.go | 2 +- .../settings/pump/test/sleep_schedule.go | 20 +-- data/types/upload/upload.go | 2 +- 23 files changed, 162 insertions(+), 134 deletions(-) diff --git a/data/data_set.go b/data/data_set.go index fe2df24efb..63e65d44d5 100644 --- a/data/data_set.go +++ b/data/data_set.go @@ -111,7 +111,7 @@ func (d *DataSetClient) Validate(validator structure.Validator) { type DataSetFilter struct { ClientName *string - IsLegacy *bool + LegacyOnly *bool Deleted *bool DeviceID *string } diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index fa205a93ee..fce59a0aa7 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -149,7 +149,7 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore options := NewDefaultDeviceDeactivateHashOptions() if getDeduplicatorVersion(dataSet) == DeviceDeactivateHashVersionLegacy { - filter := &data.DataSetFilter{IsLegacy: pointer.FromBool(true), DeviceID: dataSet.DeviceID} + filter := &data.DataSetFilter{LegacyOnly: pointer.FromBool(true), DeviceID: dataSet.DeviceID} pagination := &page.Pagination{Page: 1, Size: 1} uploads, err := repository.ListUserDataSets(ctx, *dataSet.UserID, filter, pagination) diff --git a/data/service/service/standard.go b/data/service/service/standard.go index 85b25148fb..aea30866d0 100644 --- a/data/service/service/standard.go +++ b/data/service/service/standard.go @@ -207,7 +207,7 @@ func (s *Standard) initializeDataDeduplicatorFactory() error { return errors.Wrap(err, "unable to create device deactivate hash deduplicator") } - s.Logger().Debug("Creating device truncate data set deduplicator") + s.Logger().Debug("Creating device deactivate legacy hash deduplicator") deviceDeactivateLegacyHashDeduplicator, err := dataDeduplicatorDeduplicator.NewDeviceDeactivateLegacyHash() if err != nil { diff --git a/data/store/mongo/mongo_data_set.go b/data/store/mongo/mongo_data_set.go index 218b533271..a950e14305 100644 --- a/data/store/mongo/mongo_data_set.go +++ b/data/store/mongo/mongo_data_set.go @@ -278,9 +278,12 @@ func (d *DataSetRepository) ListUserDataSets(ctx context.Context, userID string, if filter.DeviceID != nil { selector["deviceId"] = *filter.DeviceID } - - if filter.IsLegacy != nil && *filter.IsLegacy { - selector["_id"] = bson.M{"$not": bson.M{"$type": "objectId"}} + if filter.LegacyOnly != nil { + if *filter.LegacyOnly { + selector["_id"] = bson.M{"$not": bson.M{"$type": "objectId"}} + } else { + selector["_id"] = bson.M{"$type": "objectId"} + } } opts := storeStructuredMongo.FindWithPagination(pagination). diff --git a/data/types/basal/suspend/suspend_test.go b/data/types/basal/suspend/suspend_test.go index 5ee2da03ae..ecfc9934bd 100644 --- a/data/types/basal/suspend/suspend_test.go +++ b/data/types/basal/suspend/suspend_test.go @@ -142,7 +142,7 @@ var _ = Describe("Suspend", func() { }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/duration", NewMeta()), ), - Entry("duration missing;", + Entry("duration missing", func(datum *suspend.Suspend) { datum.Duration = nil datum.DurationExpected = pointer.FromInt(604800001) diff --git a/data/types/blood/blood.go b/data/types/blood/blood.go index 94ff9a74b9..813e45d87b 100644 --- a/data/types/blood/blood.go +++ b/data/types/blood/blood.go @@ -83,9 +83,13 @@ func (b *Blood) SetRawValueAndUnits(value *float64, units *string) { if units != nil { b.Raw.Set("units", *units) + } else { + b.Raw.Delete("units") } if value != nil { b.Raw.Set("value", *value) + } else { + b.Raw.Delete("value") } } diff --git a/data/types/blood/glucose/glucose_test.go b/data/types/blood/glucose/glucose_test.go index 6b1847cb67..1f51d53a6a 100644 --- a/data/types/blood/glucose/glucose_test.go +++ b/data/types/blood/glucose/glucose_test.go @@ -414,7 +414,6 @@ var _ = Describe("Glucose", func() { func(datum *glucose.Glucose, units *string) { datum.Value = nil }, func(datum *glucose.Glucose, expectedDatum *glucose.Glucose, units *string, value *float64) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) - dataBloodGlucoseTest.ExpectRaw(datum.Raw, &metadata.Metadata{"units": *units, "value": nil}) }, ), diff --git a/data/types/blood/glucose/selfmonitored/selfmonitored_test.go b/data/types/blood/glucose/selfmonitored/selfmonitored_test.go index 61394fdf91..47d6a1598c 100644 --- a/data/types/blood/glucose/selfmonitored/selfmonitored_test.go +++ b/data/types/blood/glucose/selfmonitored/selfmonitored_test.go @@ -10,11 +10,10 @@ import ( dataNormalizer "github.com/tidepool-org/platform/data/normalizer" "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" - "github.com/tidepool-org/platform/metadata" - dataTypesBloodGlucoseTest "github.com/tidepool-org/platform/data/types/blood/glucose/test" dataTypesTest "github.com/tidepool-org/platform/data/types/test" errorsTest "github.com/tidepool-org/platform/errors/test" + "github.com/tidepool-org/platform/metadata" metadataTest "github.com/tidepool-org/platform/metadata/test" "github.com/tidepool-org/platform/pointer" "github.com/tidepool-org/platform/structure" diff --git a/data/types/bolus/test/bolus.go b/data/types/bolus/test/bolus.go index 9350067681..7f1f95c5ef 100644 --- a/data/types/bolus/test/bolus.go +++ b/data/types/bolus/test/bolus.go @@ -12,7 +12,6 @@ func RandomBolus() *dataTypesBolus.Bolus { datum := randomBolus() datum.Base = *dataTypesTest.RandomBase() datum.Type = "bolus" - return datum } @@ -27,14 +26,10 @@ func randomBolus() *dataTypesBolus.Bolus { datum := &dataTypesBolus.Bolus{} datum.SubType = dataTypesTest.NewType() datum.InsulinFormulation = dataTypesInsulinTest.RandomFormulation(3) - datum.DeliveryContext = randomDeliveryContext() + datum.DeliveryContext = pointer.FromString(test.RandomStringFromArray(dataTypesBolus.DeliveryContext())) return datum } -func randomDeliveryContext() *string { - return pointer.FromString(test.RandomStringFromArray(dataTypesBolus.DeliveryContext())) -} - func CloneBolus(datum *dataTypesBolus.Bolus) *dataTypesBolus.Bolus { if datum == nil { return nil diff --git a/data/types/calculator/recommended_test.go b/data/types/calculator/recommended_test.go index 3733bb17f2..ec24e26dad 100644 --- a/data/types/calculator/recommended_test.go +++ b/data/types/calculator/recommended_test.go @@ -88,7 +88,7 @@ var _ = Describe("Recommended", func() { ), Entry("carbohydrate out of range (lower)", func(datum *calculator.Recommended) { datum.Carbohydrate = pointer.FromFloat64(-0.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-0.1, 0, calculator.CarbohydrateMaximum), "/carb"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(calculator.CarbohydrateMinimum-0.1, calculator.CarbohydrateMinimum, calculator.CarbohydrateMaximum), "/carb"), ), Entry("carbohydrate in range (lower)", func(datum *calculator.Recommended) { datum.Carbohydrate = pointer.FromFloat64(0.0) }, @@ -100,14 +100,14 @@ var _ = Describe("Recommended", func() { func(datum *calculator.Recommended) { datum.Carbohydrate = pointer.FromFloat64(calculator.CarbohydrateMaximum + 0.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(calculator.CarbohydrateMaximum+0.1, 0, calculator.CarbohydrateMaximum), "/carb"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(calculator.CarbohydrateMaximum+0.1, calculator.CarbohydrateMinimum, calculator.CarbohydrateMaximum), "/carb"), ), Entry("correction missing", func(datum *calculator.Recommended) { datum.Correction = nil }, ), Entry("correction out of range (lower)", func(datum *calculator.Recommended) { datum.Correction = pointer.FromFloat64(-250.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-250.1, calculator.CorrectionMinimum, calculator.CorrectionMaximum), "/correction"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(calculator.CorrectionMinimum-0.1, calculator.CorrectionMinimum, calculator.CorrectionMaximum), "/correction"), ), Entry("correction in range (lower)", func(datum *calculator.Recommended) { datum.Correction = pointer.FromFloat64(-100.0) }, @@ -117,14 +117,14 @@ var _ = Describe("Recommended", func() { ), Entry("correction out of range (upper)", func(datum *calculator.Recommended) { datum.Correction = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(250.1, calculator.CorrectionMinimum, calculator.CorrectionMaximum), "/correction"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(calculator.CorrectionMaximum+0.1, calculator.CorrectionMinimum, calculator.CorrectionMaximum), "/correction"), ), Entry("net missing", func(datum *calculator.Recommended) { datum.Net = nil }, ), Entry("net out of range (lower)", func(datum *calculator.Recommended) { datum.Net = pointer.FromFloat64(-250.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-250.1, calculator.NetMinimum, calculator.NetMaximum), "/net"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(calculator.NetMinimum-0.1, calculator.NetMinimum, calculator.NetMaximum), "/net"), ), Entry("net in range (lower)", func(datum *calculator.Recommended) { datum.Net = pointer.FromFloat64(-100.0) }, @@ -134,7 +134,7 @@ var _ = Describe("Recommended", func() { ), Entry("net out of range (upper)", func(datum *calculator.Recommended) { datum.Net = pointer.FromFloat64(250.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(250.1, calculator.NetMinimum, calculator.NetMaximum), "/net"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(calculator.NetMaximum+0.1, calculator.NetMinimum, calculator.NetMaximum), "/net"), ), Entry("multiple errors", func(datum *calculator.Recommended) { @@ -142,9 +142,9 @@ var _ = Describe("Recommended", func() { datum.Correction = pointer.FromFloat64(-250.1) datum.Net = pointer.FromFloat64(-250.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-0.1, 0, calculator.InsulinCarbohydrateRatioMaximum), "/carb"), - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-250.1, calculator.CorrectionMinimum, calculator.CorrectionMaximum), "/correction"), - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-250.1, calculator.NetMinimum, calculator.NetMaximum), "/net"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(calculator.CarbohydrateMinimum-0.1, calculator.CarbohydrateMinimum, calculator.InsulinCarbohydrateRatioMaximum), "/carb"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(calculator.CorrectionMinimum-0.1, calculator.CorrectionMinimum, calculator.CorrectionMaximum), "/correction"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(calculator.NetMinimum-0.1, calculator.NetMinimum, calculator.NetMaximum), "/net"), ), ) }) diff --git a/data/types/common/day.go b/data/types/common/day.go index 6546694cd6..68e7d150c2 100644 --- a/data/types/common/day.go +++ b/data/types/common/day.go @@ -1,10 +1,10 @@ package common import ( - "errors" "slices" "strings" + "github.com/tidepool-org/platform/errors" "github.com/tidepool-org/platform/structure" "github.com/tidepool-org/platform/structure/validator" ) @@ -41,15 +41,21 @@ func (d DaysOfWeekByDayIndex) Swap(i int, j int) { } func (d DaysOfWeekByDayIndex) Less(i int, j int) bool { - a, errA := DayIndex(d[i]) - if errA != nil { - return false + iDay := d[i] + jDay := d[j] + iDayIndex, iErr := DayIndex(iDay) + jDayIndex, jErr := DayIndex(jDay) + if iErr != nil { + if jErr != nil { + return iDay < jDay + } else { + return false + } + } else if jErr != nil { + return true + } else { + return iDayIndex < jDayIndex } - b, errB := DayIndex(d[j]) - if errB != nil { - return false - } - return a < b } func DayIndex(day string) (int, error) { diff --git a/data/types/common/day_test.go b/data/types/common/day_test.go index 94e8b53c1a..d5b9936761 100644 --- a/data/types/common/day_test.go +++ b/data/types/common/day_test.go @@ -1,12 +1,11 @@ package common_test import ( - "errors" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/tidepool-org/platform/data/types/common" + "github.com/tidepool-org/platform/errors" "github.com/tidepool-org/platform/structure/validator" ) @@ -61,7 +60,7 @@ var _ = Describe("Day", func() { if expectedErr == nil { Expect(actualError).To(BeNil()) } else { - Expect(actualError).To(Equal(expectedErr)) + Expect(actualError.Error()).To(Equal(expectedErr.Error())) } }, Entry("is an empty string", "", 0, errors.New("invalid day of the week")), diff --git a/data/types/device/device_test.go b/data/types/device/device_test.go index 57a7926ca0..bd9a083f7b 100644 --- a/data/types/device/device_test.go +++ b/data/types/device/device_test.go @@ -6,7 +6,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/tidepool-org/platform/data/types" + dataTypes "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/data/types/device" dataTypesDeviceTest "github.com/tidepool-org/platform/data/types/device/test" dataTypesTest "github.com/tidepool-org/platform/data/types/test" @@ -137,18 +137,18 @@ var _ = Describe("Device", func() { It("returns error if sub type is empty", func() { datum.SubType = "" - identityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) + identityFields, err := datum.IdentityFields(dataTypes.LegacyIdentityFieldsVersion) Expect(err).To(MatchError("sub type is empty")) Expect(identityFields).To(BeEmpty()) }) It("returns the expected legacy identity fields", func() { datum.DeviceID = pointer.FromString("some-device") - t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") + t, err := time.Parse(dataTypes.TimeFormat, "2023-05-13T15:51:58Z") Expect(err).ToNot(HaveOccurred()) datum.Time = pointer.FromTime(t) datum.SubType = "some-sub-type" - legacyIdentityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) + legacyIdentityFields, err := datum.IdentityFields(dataTypes.LegacyIdentityFieldsVersion) Expect(err).ToNot(HaveOccurred()) Expect(legacyIdentityFields).To(Equal([]string{"deviceEvent", "some-sub-type", "2023-05-13T15:51:58.000Z", "some-device"})) }) diff --git a/data/types/food/food_test.go b/data/types/food/food_test.go index 1e123d96c2..70f8f0fade 100644 --- a/data/types/food/food_test.go +++ b/data/types/food/food_test.go @@ -7,7 +7,6 @@ import ( . "github.com/onsi/gomega" dataNormalizer "github.com/tidepool-org/platform/data/normalizer" - "github.com/tidepool-org/platform/data/types" dataTypes "github.com/tidepool-org/platform/data/types" dataTypesFood "github.com/tidepool-org/platform/data/types/food" dataTypesFoodTest "github.com/tidepool-org/platform/data/types/food/test" @@ -439,10 +438,10 @@ var _ = Describe("Food", func() { It("returns the expected legacy identity fields", func() { datum := dataTypesFoodTest.RandomFood(3) datum.DeviceID = pointer.FromString("some-device") - t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") + t, err := time.Parse(dataTypes.TimeFormat, "2023-05-13T15:51:58Z") Expect(err).ToNot(HaveOccurred()) datum.Time = pointer.FromTime(t) - legacyIdentityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) + legacyIdentityFields, err := datum.IdentityFields(dataTypes.LegacyIdentityFieldsVersion) Expect(err).ToNot(HaveOccurred()) Expect(legacyIdentityFields).To(Equal([]string{"food", "some-device", "2023-05-13T15:51:58.000Z"})) }) diff --git a/data/types/settings/cgm/cgm_test.go b/data/types/settings/cgm/cgm_test.go index 683491b06f..b3da96ca89 100644 --- a/data/types/settings/cgm/cgm_test.go +++ b/data/types/settings/cgm/cgm_test.go @@ -9,7 +9,6 @@ import ( dataBloodGlucoseTest "github.com/tidepool-org/platform/data/blood/glucose/test" dataNormalizer "github.com/tidepool-org/platform/data/normalizer" - "github.com/tidepool-org/platform/data/types" dataTypes "github.com/tidepool-org/platform/data/types" dataTypesSettingsCgm "github.com/tidepool-org/platform/data/types/settings/cgm" dataTypesSettingsCgmTest "github.com/tidepool-org/platform/data/types/settings/cgm/test" @@ -601,10 +600,10 @@ var _ = Describe("CGM", func() { It("returns the expected legacy identity fields", func() { datum := dataTypesSettingsCgmTest.RandomCGM(pointer.FromString("mmol/l")) datum.DeviceID = pointer.FromString("some-cgm-device") - t, err := time.Parse(types.TimeFormat, "2023-05-13T15:51:58Z") + t, err := time.Parse(dataTypes.TimeFormat, "2023-05-13T15:51:58Z") Expect(err).ToNot(HaveOccurred()) datum.Time = pointer.FromTime(t) - legacyIdentityFields, err := datum.IdentityFields(types.LegacyIdentityFieldsVersion) + legacyIdentityFields, err := datum.IdentityFields(dataTypes.LegacyIdentityFieldsVersion) Expect(err).ToNot(HaveOccurred()) Expect(legacyIdentityFields).To(Equal([]string{"cgmSettings", "2023-05-13T15:51:58.000Z", "some-cgm-device"})) }) diff --git a/data/types/settings/pump/bolus_amount_maximum_test.go b/data/types/settings/pump/bolus_amount_maximum_test.go index efb4e3f503..d30290822a 100644 --- a/data/types/settings/pump/bolus_amount_maximum_test.go +++ b/data/types/settings/pump/bolus_amount_maximum_test.go @@ -6,10 +6,9 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" - dataNormalizer "github.com/tidepool-org/platform/data/normalizer" "github.com/tidepool-org/platform/data/types/settings/pump" + pumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" dataTypesTest "github.com/tidepool-org/platform/data/types/test" errorsTest "github.com/tidepool-org/platform/errors/test" "github.com/tidepool-org/platform/pointer" @@ -70,7 +69,7 @@ var _ = Describe("BolusAmountMaximum", func() { Entry("units Units", func(datum *pump.BolusAmountMaximum) { datum.Units = pointer.FromString("Units") - datum.Value = pointer.FromFloat64(0.0) + datum.Value = pointer.FromFloat64(pump.BolusAmountMaximumValueUnitsMinimum) }, ), Entry("units missing; value missing", @@ -84,14 +83,14 @@ var _ = Describe("BolusAmountMaximum", func() { Entry("units missing; value out of range (lower)", func(datum *pump.BolusAmountMaximum) { datum.Units = nil - datum.Value = pointer.FromFloat64(-0.1) + datum.Value = pointer.FromFloat64(pump.BolusAmountMaximumValueUnitsMinimum - 0.1) }, errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/units"), ), Entry("units missing; value in range (lower)", func(datum *pump.BolusAmountMaximum) { datum.Units = nil - datum.Value = pointer.FromFloat64(0.0) + datum.Value = pointer.FromFloat64(pump.BolusAmountMaximumValueUnitsMinimum) }, errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/units"), ), @@ -105,7 +104,7 @@ var _ = Describe("BolusAmountMaximum", func() { Entry("units missing; value out of range (upper)", func(datum *pump.BolusAmountMaximum) { datum.Units = nil - datum.Value = pointer.FromFloat64(250.1) + datum.Value = pointer.FromFloat64(pump.BolusAmountMaximumValueUnitsMaximum + 0.1) }, errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/units"), ), @@ -120,14 +119,14 @@ var _ = Describe("BolusAmountMaximum", func() { Entry("units invalid; value out of range (lower)", func(datum *pump.BolusAmountMaximum) { datum.Units = pointer.FromString("invalid") - datum.Value = pointer.FromFloat64(-0.1) + datum.Value = pointer.FromFloat64(pump.BolusAmountMaximumValueUnitsMinimum - 0.1) }, errorsTest.WithPointerSource(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"Units"}), "/units"), ), Entry("units invalid; value in range (lower)", func(datum *pump.BolusAmountMaximum) { datum.Units = pointer.FromString("invalid") - datum.Value = pointer.FromFloat64(0.0) + datum.Value = pointer.FromFloat64(pump.BolusAmountMaximumValueUnitsMinimum) }, errorsTest.WithPointerSource(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"Units"}), "/units"), ), @@ -141,7 +140,7 @@ var _ = Describe("BolusAmountMaximum", func() { Entry("units invalid; value out of range (upper)", func(datum *pump.BolusAmountMaximum) { datum.Units = pointer.FromString("invalid") - datum.Value = pointer.FromFloat64(250.1) + datum.Value = pointer.FromFloat64(pump.BolusAmountMaximumValueUnitsMaximum + 0.1) }, errorsTest.WithPointerSource(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"Units"}), "/units"), ), @@ -155,14 +154,14 @@ var _ = Describe("BolusAmountMaximum", func() { Entry("units Units; value out of range (lower)", func(datum *pump.BolusAmountMaximum) { datum.Units = pointer.FromString("Units") - datum.Value = pointer.FromFloat64(-0.1) + datum.Value = pointer.FromFloat64(pump.BolusAmountMaximumValueUnitsMinimum - 0.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-0.1, 0.0, pump.BolusAmountMaximumValueUnitsMaximum), "/value"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(pump.BolusAmountMaximumValueUnitsMinimum-0.1, pump.BolusAmountMaximumValueUnitsMinimum, pump.BolusAmountMaximumValueUnitsMaximum), "/value"), ), Entry("units Units; value in range (lower)", func(datum *pump.BolusAmountMaximum) { datum.Units = pointer.FromString("Units") - datum.Value = pointer.FromFloat64(0.0) + datum.Value = pointer.FromFloat64(pump.BolusAmountMaximumValueUnitsMinimum) }, ), Entry("units Units; value in range (upper)", @@ -174,9 +173,9 @@ var _ = Describe("BolusAmountMaximum", func() { Entry("units Units; value out of range (upper)", func(datum *pump.BolusAmountMaximum) { datum.Units = pointer.FromString("Units") - datum.Value = pointer.FromFloat64(250.1) + datum.Value = pointer.FromFloat64(pump.BolusAmountMaximumValueUnitsMaximum + 0.1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(250.1, 0.0, pump.BolusAmountMaximumValueUnitsMaximum), "/value"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(pump.BolusAmountMaximumValueUnitsMaximum+0.1, pump.BolusAmountMaximumValueUnitsMinimum, pump.BolusAmountMaximumValueUnitsMaximum), "/value"), ), Entry("multiple errors", func(datum *pump.BolusAmountMaximum) { @@ -232,7 +231,7 @@ var _ = Describe("BolusAmountMaximum", func() { It("returns expected range for units Units", func() { minimum, maximum := pump.BolusAmountMaximumValueRangeForUnits(pointer.FromString("Units")) - Expect(minimum).To(Equal(0.0)) + Expect(minimum).To(Equal(pump.BolusAmountMaximumValueUnitsMinimum)) Expect(maximum).To(Equal(pump.BolusAmountMaximumValueUnitsMaximum)) }) }) diff --git a/data/types/settings/pump/bolus_test.go b/data/types/settings/pump/bolus_test.go index 54c715393d..f288bff533 100644 --- a/data/types/settings/pump/bolus_test.go +++ b/data/types/settings/pump/bolus_test.go @@ -99,8 +99,7 @@ var _ = Describe("Bolus", func() { }) }) - Context("Boluses", func() { - + Context("BolusMap", func() { Context("Validate", func() { DescribeTable("validates the datum", func(mutator func(datum *pump.BolusMap), expectedErrors ...error) { diff --git a/data/types/settings/pump/pump_test.go b/data/types/settings/pump/pump_test.go index 7f4bc1cf84..1d02564d19 100644 --- a/data/types/settings/pump/pump_test.go +++ b/data/types/settings/pump/pump_test.go @@ -670,18 +670,20 @@ var _ = Describe("Pump", func() { Entry("sleep schedules invalid", pointer.FromString("mmol/L"), func(datum *pump.Pump, unitsBloodGlucose *string) { - datum.SleepSchedules = pumpTest.RandomSleepSchedules(2) + datum.SleepSchedules = pumpTest.RandomSleepScheduleMap(2) + (*datum.SleepSchedules)[pumpTest.SleepScheduleName(1)].Start = pointer.FromInt(pump.SleepSchedulesMidnightOffsetMaximum / 2) (*datum.SleepSchedules)[pumpTest.SleepScheduleName(1)].End = pointer.FromInt(pump.SleepSchedulesMidnightOffsetMaximum + 1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange( - pump.SleepSchedulesMidnightOffsetMaximum+1, 0, + pump.SleepSchedulesMidnightOffsetMaximum+1, + pump.SleepSchedulesMidnightOffsetMaximum/2, pump.SleepSchedulesMidnightOffsetMaximum), fmt.Sprintf("/sleepSchedules/%s/end", pumpTest.SleepScheduleName(1)), pumpTest.NewMeta()), ), Entry("sleep schedules valid", pointer.FromString("mmol/L"), func(datum *pump.Pump, unitsBloodGlucose *string) { - datum.SleepSchedules = pumpTest.RandomSleepSchedules(3) + datum.SleepSchedules = pumpTest.RandomSleepScheduleMap(3) }, ), Entry("software version missing", diff --git a/data/types/settings/pump/sleep_schedule.go b/data/types/settings/pump/sleep_schedule.go index 11a9cd0c39..e1da568047 100644 --- a/data/types/settings/pump/sleep_schedule.go +++ b/data/types/settings/pump/sleep_schedule.go @@ -104,11 +104,14 @@ func (s *SleepSchedule) Parse(parser structure.ObjectParser) { func (s *SleepSchedule) Validate(validator structure.Validator) { validator.Bool("enabled", s.Enabled).Exists() - if s.Enabled != nil { - if *s.Enabled { - validator.StringArray("days", s.Days).Exists().EachUsing(dataTypesCommon.DayOfWeekValidator).EachUnique() - validator.Int("start", s.Start).Exists().InRange(SleepSchedulesMidnightOffsetMinimum, SleepSchedulesMidnightOffsetMaximum) - validator.Int("end", s.End).Exists().InRange(SleepSchedulesMidnightOffsetMinimum, SleepSchedulesMidnightOffsetMaximum) + if s.Enabled != nil && *s.Enabled { + validator.StringArray("days", s.Days).Exists().EachUsing(dataTypesCommon.DayOfWeekValidator).EachUnique() + validator.Int("start", s.Start).Exists().InRange(SleepSchedulesMidnightOffsetMinimum, SleepSchedulesMidnightOffsetMaximum) + + if endValidator := validator.Int("end", s.End); s.Start != nil { + endValidator.Exists().InRange(*s.Start, SleepSchedulesMidnightOffsetMaximum) + } else { + endValidator.Exists().InRange(SleepSchedulesMidnightOffsetMinimum, SleepSchedulesMidnightOffsetMaximum) } } } diff --git a/data/types/settings/pump/sleep_schedule_test.go b/data/types/settings/pump/sleep_schedule_test.go index b0710b821f..2903a86fda 100644 --- a/data/types/settings/pump/sleep_schedule_test.go +++ b/data/types/settings/pump/sleep_schedule_test.go @@ -30,7 +30,7 @@ var _ = Describe("SleepSchedule", func() { Context("Validate", func() { DescribeTable("validates the datum", func(mutator func(datum *dataTypesSettingsPump.SleepScheduleMap), expectedErrors ...error) { - datum := dataTypesSettingsPumpTest.RandomSleepSchedules(3) + datum := dataTypesSettingsPumpTest.RandomSleepScheduleMap(3) mutator(datum) errorsTest.ExpectEqual(structureValidator.New().Validate(datum), expectedErrors...) }, @@ -44,12 +44,12 @@ var _ = Describe("SleepSchedule", func() { ), Entry("has one", func(datum *dataTypesSettingsPump.SleepScheduleMap) { - *datum = *dataTypesSettingsPumpTest.RandomSleepSchedules(1) + *datum = *dataTypesSettingsPumpTest.RandomSleepScheduleMap(1) }, ), Entry("has many", func(datum *dataTypesSettingsPump.SleepScheduleMap) { - *datum = *dataTypesSettingsPumpTest.RandomSleepSchedules(3) + *datum = *dataTypesSettingsPumpTest.RandomSleepScheduleMap(3) }, ), Entry("entry missing", @@ -60,7 +60,7 @@ var _ = Describe("SleepSchedule", func() { ), Entry("multiple errors", func(datum *dataTypesSettingsPump.SleepScheduleMap) { - *datum = *dataTypesSettingsPumpTest.RandomSleepSchedules(3) + *datum = *dataTypesSettingsPumpTest.RandomSleepScheduleMap(3) (*datum)[dataTypesSettingsPumpTest.SleepScheduleName(1)] = nil }, errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), fmt.Sprintf("/%s", dataTypesSettingsPumpTest.SleepScheduleName(1))), @@ -98,119 +98,141 @@ var _ = Describe("SleepSchedule", func() { Context("Validate", func() { DescribeTable("validates the datum", - func(mutator func(datum *dataTypesSettingsPump.SleepSchedule), expectedErrors ...error) { + func(mutator func(datum *dataTypesSettingsPump.SleepSchedule) []error) { datum := dataTypesSettingsPumpTest.RandomSleepSchedule() - mutator(datum) + expectedErrors := mutator(datum) errorsTest.ExpectEqual(structureValidator.New().Validate(datum), expectedErrors...) }, Entry("succeeds", - func(datum *dataTypesSettingsPump.SleepSchedule) {}, + func(datum *dataTypesSettingsPump.SleepSchedule) []error { return nil }, ), Entry("enabled missing", - func(datum *dataTypesSettingsPump.SleepSchedule) { datum.Enabled = nil }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/enabled"), + func(datum *dataTypesSettingsPump.SleepSchedule) []error { + datum.Enabled = nil + return []error{errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/enabled")} + }, ), Entry("days missing", - func(datum *dataTypesSettingsPump.SleepSchedule) { + func(datum *dataTypesSettingsPump.SleepSchedule) []error { datum.Days = nil + return []error{errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/days")} }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/days"), ), Entry("days contains invalid", - func(datum *dataTypesSettingsPump.SleepSchedule) { + func(datum *dataTypesSettingsPump.SleepSchedule) []error { datum.Days = pointer.FromStringArray(append([]string{"invalid"}, test.RandomStringArrayFromRangeAndArrayWithoutDuplicates(0, len(dataTypesCommon.DaysOfWeek())-1, dataTypesCommon.DaysOfWeek())...)) + return []error{errorsTest.WithPointerSource(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"}), "/days/0")} }, - errorsTest.WithPointerSource(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"}), "/days/0"), ), Entry("days contains duplicate", - func(datum *dataTypesSettingsPump.SleepSchedule) { + func(datum *dataTypesSettingsPump.SleepSchedule) []error { duplicate := test.RandomStringFromArray(dataTypesCommon.DaysOfWeek()) datum.Days = pointer.FromStringArray([]string{duplicate, duplicate}) + return []error{errorsTest.WithPointerSource(structureValidator.ErrorValueDuplicate(), "/days/1")} + }, - errorsTest.WithPointerSource(structureValidator.ErrorValueDuplicate(), "/days/1"), ), Entry("days valid", - func(datum *dataTypesSettingsPump.SleepSchedule) { + func(datum *dataTypesSettingsPump.SleepSchedule) []error { datum.Days = pointer.FromStringArray(test.RandomStringArrayFromRangeAndArrayWithoutDuplicates(1, len(dataTypesCommon.DaysOfWeek()), dataTypesCommon.DaysOfWeek())) + return nil }, ), Entry("start missing", - func(datum *dataTypesSettingsPump.SleepSchedule) { + func(datum *dataTypesSettingsPump.SleepSchedule) []error { datum.Start = nil + return []error{errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/start")} }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/start"), ), Entry("start out of range (lower)", - func(datum *dataTypesSettingsPump.SleepSchedule) { + func(datum *dataTypesSettingsPump.SleepSchedule) []error { datum.Start = pointer.FromInt(-1) + return []error{ + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange( + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum-1, + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum, + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum), "/start"), + } + }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange( - dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum-1, - dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum, - dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum), "/start"), ), Entry("start in range (lower)", - func(datum *dataTypesSettingsPump.SleepSchedule) { + func(datum *dataTypesSettingsPump.SleepSchedule) []error { datum.Start = pointer.FromInt(dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum) + return nil }, ), Entry("start in range (upper)", - func(datum *dataTypesSettingsPump.SleepSchedule) { - datum.Start = pointer.FromInt(dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum) + func(datum *dataTypesSettingsPump.SleepSchedule) []error { + datum.Start = pointer.FromInt(dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum - 1) + datum.End = pointer.FromInt(*datum.Start + 1) + return nil }, ), Entry("start out of range (upper)", - func(datum *dataTypesSettingsPump.SleepSchedule) { + func(datum *dataTypesSettingsPump.SleepSchedule) []error { datum.Start = pointer.FromInt(dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum + 1) + return []error{errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange( + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum+1, + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum, + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum), "/start"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange( + *datum.End, + *datum.Start, + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum), "/end"), + } }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange( - dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum+1, - dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum, - dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum), "/start"), ), Entry("end missing", - func(datum *dataTypesSettingsPump.SleepSchedule) { + func(datum *dataTypesSettingsPump.SleepSchedule) []error { datum.End = nil + return []error{errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/end")} }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/end"), ), Entry("end out of range (lower)", - func(datum *dataTypesSettingsPump.SleepSchedule) { + func(datum *dataTypesSettingsPump.SleepSchedule) []error { datum.End = pointer.FromInt(-1) + return []error{errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange( + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum-1, + *datum.Start, + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum), "/end")} }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange( - dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum-1, - dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum, - dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum), "/end"), ), Entry("end in range (lower)", - func(datum *dataTypesSettingsPump.SleepSchedule) { - datum.End = pointer.FromInt(dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum) + func(datum *dataTypesSettingsPump.SleepSchedule) []error { + datum.End = pointer.FromInt(*datum.Start) + return nil }, ), Entry("end in range (upper)", - func(datum *dataTypesSettingsPump.SleepSchedule) { + func(datum *dataTypesSettingsPump.SleepSchedule) []error { datum.End = pointer.FromInt(dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum) + return nil }, ), Entry("end out of range (upper)", - func(datum *dataTypesSettingsPump.SleepSchedule) { + func(datum *dataTypesSettingsPump.SleepSchedule) []error { datum.End = pointer.FromInt(dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum + 1) + return []error{ + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange( + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum+1, + *datum.Start, + dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum), "/end"), + } }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange( - dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum+1, - dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum, - dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum), "/end"), ), Entry("multiple errors", - func(datum *dataTypesSettingsPump.SleepSchedule) { + func(datum *dataTypesSettingsPump.SleepSchedule) []error { datum.Days = nil datum.Start = nil datum.End = nil + + return []error{ + errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/days"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/start"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/end"), + } }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/days"), - errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/start"), - errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/end"), ), ) }) diff --git a/data/types/settings/pump/test/bolus.go b/data/types/settings/pump/test/bolus.go index 52cac453c2..7fe52a4562 100644 --- a/data/types/settings/pump/test/bolus.go +++ b/data/types/settings/pump/test/bolus.go @@ -34,7 +34,7 @@ func NewRandomBolusMap(minimumLength int, maximumLength int) *dataTypesSettingsP datum := dataTypesSettingsPump.NewBolusMap() count := test.RandomIntFromRange(minimumLength, maximumLength) if count == 0 { - return nil + return datum } for i := 0; i < count; i++ { diff --git a/data/types/settings/pump/test/sleep_schedule.go b/data/types/settings/pump/test/sleep_schedule.go index bc8c547993..be6fe7e6e4 100644 --- a/data/types/settings/pump/test/sleep_schedule.go +++ b/data/types/settings/pump/test/sleep_schedule.go @@ -13,7 +13,7 @@ func SleepScheduleName(index int) string { return fmt.Sprintf("schedule-%d", index) } -func RandomSleepSchedules(count int) *dataTypesSettingsPump.SleepScheduleMap { +func RandomSleepScheduleMap(count int) *dataTypesSettingsPump.SleepScheduleMap { datum := dataTypesSettingsPump.NewSleepScheduleMap() for i := 0; i < count; i++ { (*datum)[SleepScheduleName(i)] = RandomSleepSchedule() @@ -21,26 +21,26 @@ func RandomSleepSchedules(count int) *dataTypesSettingsPump.SleepScheduleMap { return datum } -func CloneSleepSchedules(datum *dataTypesSettingsPump.SleepScheduleMap) *dataTypesSettingsPump.SleepScheduleMap { +func CloneSleepScheduleMap(datum *dataTypesSettingsPump.SleepScheduleMap) *dataTypesSettingsPump.SleepScheduleMap { if datum == nil { return nil } clone := make(dataTypesSettingsPump.SleepScheduleMap, len(*datum)) - for index, d := range *datum { - clone[index] = CloneSleepSchedule(d) + for k, v := range *datum { + clone[k] = CloneSleepSchedule(v) } return &clone } -func NewArrayFromSleepSchedules(datum *dataTypesSettingsPump.SleepScheduleMap, objectFormat test.ObjectFormat) []interface{} { +func NewObjectFromSleepScheduleMap(datum *dataTypesSettingsPump.SleepScheduleMap, objectFormat test.ObjectFormat) map[string]interface{} { if datum == nil { return nil } - array := []interface{}{} - for _, d := range *datum { - array = append(array, NewObjectFromSleepSchedule(d, objectFormat)) + object := map[string]interface{}{} + for k, v := range *datum { + object[k] = NewObjectFromSleepSchedule(v, objectFormat) } - return array + return object } func RandomSleepSchedule() *dataTypesSettingsPump.SleepSchedule { @@ -49,7 +49,7 @@ func RandomSleepSchedule() *dataTypesSettingsPump.SleepSchedule { datum.Enabled = pointer.FromBool(true) datum.Days = pointer.FromStringArray(test.RandomStringArrayFromRangeAndArrayWithoutDuplicates(1, len(dataTypesCommon.DaysOfWeek()), dataTypesCommon.DaysOfWeek())) datum.Start = pointer.FromInt(test.RandomIntFromRange(dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum, dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum)) - datum.End = pointer.FromInt(test.RandomIntFromRange(dataTypesSettingsPump.SleepSchedulesMidnightOffsetMinimum, dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum)) + datum.End = pointer.FromInt(test.RandomIntFromRange(*datum.Start, dataTypesSettingsPump.SleepSchedulesMidnightOffsetMaximum)) return datum } diff --git a/data/types/upload/upload.go b/data/types/upload/upload.go index 2e4aa8c5e7..282eba64ca 100644 --- a/data/types/upload/upload.go +++ b/data/types/upload/upload.go @@ -214,5 +214,5 @@ func (u *Upload) HasDeduplicatorName() bool { } func (u *Upload) HasDeduplicatorNameMatch(name string) bool { - return u.HasDeduplicatorName() && u.Deduplicator.HasNameMatch(name) + return u.Deduplicator != nil && u.Deduplicator.HasNameMatch(name) } From 086b4fdd01270ee4512bc94a9bb343222c904b4e Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 22 Oct 2024 13:44:53 +1300 Subject: [PATCH 403/413] cleanup --- data/deduplicator/deduplicator/device_deactivate_hash.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index fce59a0aa7..c119a7ed94 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -45,7 +45,7 @@ type DeviceDeactivateHash struct { } func NewDeviceDeactivateLegacyHash() (*DeviceDeactivateHash, error) { - base, err := NewBase(DeviceDeactivateHashName, string(DeviceDeactivateHashVersionLegacy)) + base, err := NewBase(DeviceDeactivateHashName, DeviceDeactivateHashVersionLegacy) if err != nil { return nil, err } @@ -56,7 +56,7 @@ func NewDeviceDeactivateLegacyHash() (*DeviceDeactivateHash, error) { } func NewDeviceDeactivateHash() (*DeviceDeactivateHash, error) { - base, err := NewBase(DeviceDeactivateHashName, string(DeviceDeactivateHashVersionCurrent)) + base, err := NewBase(DeviceDeactivateHashName, DeviceDeactivateHashVersionCurrent) if err != nil { return nil, err } @@ -112,7 +112,6 @@ func (d *DeviceDeactivateHash) New(dataSet *dataTypesUpload.Upload) (bool, error if dataSet.HasDeduplicatorName() { return d.Get(dataSet) } - //if hash version is set retur true return getDeduplicatorVersion(dataSet) != DeviceDeactivateHashVersionUnknown, nil } From 7492d22d26831f32fa03e5186e8236b973f681b0 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 23 Oct 2024 08:20:41 +1300 Subject: [PATCH 404/413] cleanup identityFields creation --- data/deduplicator/deduplicator/hash_test.go | 41 ++++------ data/types/basal/basal.go | 37 ++++++--- data/types/base.go | 91 ++++++++++----------- data/types/base_test.go | 50 +++++------ data/types/bolus/bolus.go | 39 ++++++--- data/types/device/device.go | 40 ++++++--- data/types/settings/cgm/cgm.go | 23 ++++-- 7 files changed, 184 insertions(+), 137 deletions(-) diff --git a/data/deduplicator/deduplicator/hash_test.go b/data/deduplicator/deduplicator/hash_test.go index 6b212cc638..01ba7ef3f1 100644 --- a/data/deduplicator/deduplicator/hash_test.go +++ b/data/deduplicator/deduplicator/hash_test.go @@ -6,15 +6,14 @@ import ( "github.com/tidepool-org/platform/data" dataDeduplicatorDeduplicator "github.com/tidepool-org/platform/data/deduplicator/deduplicator" - "github.com/tidepool-org/platform/structure" - "github.com/tidepool-org/platform/test" - dataNormalizer "github.com/tidepool-org/platform/data/normalizer" dataTest "github.com/tidepool-org/platform/data/test" "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" dataTypesBloodGlucoseTest "github.com/tidepool-org/platform/data/types/blood/glucose/test" "github.com/tidepool-org/platform/errors" "github.com/tidepool-org/platform/pointer" + "github.com/tidepool-org/platform/structure" + "github.com/tidepool-org/platform/test" userTest "github.com/tidepool-org/platform/user/test" ) @@ -233,29 +232,23 @@ var _ = Describe("Hash", func() { }) DescribeTable("hash from legacy identity tests", - func(fields []string, expectedHash string, expectedErr error) { + func(fields []string, expectedHash string) { actualHash, actualErr := dataDeduplicatorDeduplicator.GenerateLegacyIdentityHash(fields) - if expectedErr != nil { - Expect(actualErr).To(Equal(expectedErr)) - } else { - Expect(actualHash).To(Equal(expectedHash)) - Expect(actualErr).To(BeNil()) - } + Expect(actualHash).To(Equal(expectedHash)) + Expect(actualErr).ToNot(HaveOccurred()) }, - Entry("smbg id", []string{"smbg", "tools", "2014-06-11T11:12:43.029Z", "5.550747991045533"}, "e2ihon9nqcro96c4uugb4ftdnr07nqok", nil), - Entry("smbg id", []string{"smbg", "tools", "2014-06-11T17:57:01.703Z", "4.5"}, "c14eds071pp5gsirfmgmsclbcahs8th0", nil), - Entry("smbg id", []string{"smbg", "tools", "2015-07-04T10:13:00.000Z", "4.9"}, "rk2htms97m7hipdu5lrso7ufd3pedm6n", nil), - Entry("smbg id", []string{"smbg", "tools", "2015-07-04T10:13:00.000Z", "4.8"}, "urrkdln86rl4vhqckps6gnupg5njqk6n", nil), - - Entry("cbg id", []string{"cbg", "tools", "2014-06-11T11:12:43.029Z"}, "eb12p6h892pmd0hhccpt2r17muc407o0", nil), - Entry("cbg id", []string{"cbg", "tools", "2014-06-11T17:57:01.703Z"}, "ha2ogn1kenqqhseed504sqnanhnclg5s", nil), - Entry("cbg id", []string{"cbg", "tools", "2014-06-12T11:12:43.029Z"}, "i922lobl3kron3t81pjap31anopkspvb", nil), - Entry("cbg id", []string{"cbg", "DexHealthKit_Dexcom:com.dexcom.Share2:3.0.4.17", "2015-12-21T11:23:08Z"}, "nsikjhfaprplpq78hc7di2lu5qpt1e3k", nil), - - Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T00:00:00.000Z"}, "kmm427pfbrc6rugtmbuli8j4q61u17uk", nil), - Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T06:00:00.000Z"}, "cjou7vscvp8ogv34d6vejootulqfn3jd", nil), - Entry("basal id", []string{"basal", "temp", "tools", "2014-06-11T09:00:00.000Z"}, "tn33bjb0241j9qh4jg9vdnf1g6k1g9r8", nil), - Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T19:00:00.000Z"}, "kftn188l8rjuvma3qkd3iqg34t0plajp", nil), + Entry("smbg id", []string{"smbg", "tools", "2014-06-11T11:12:43.029Z", "5.550747991045533"}, "e2ihon9nqcro96c4uugb4ftdnr07nqok"), + Entry("smbg id", []string{"smbg", "tools", "2014-06-11T17:57:01.703Z", "4.5"}, "c14eds071pp5gsirfmgmsclbcahs8th0"), + Entry("smbg id", []string{"smbg", "tools", "2015-07-04T10:13:00.000Z", "4.9"}, "rk2htms97m7hipdu5lrso7ufd3pedm6n"), + Entry("smbg id", []string{"smbg", "tools", "2015-07-04T10:13:00.000Z", "4.8"}, "urrkdln86rl4vhqckps6gnupg5njqk6n"), + Entry("cbg id", []string{"cbg", "tools", "2014-06-11T11:12:43.029Z"}, "eb12p6h892pmd0hhccpt2r17muc407o0"), + Entry("cbg id", []string{"cbg", "tools", "2014-06-11T17:57:01.703Z"}, "ha2ogn1kenqqhseed504sqnanhnclg5s"), + Entry("cbg id", []string{"cbg", "tools", "2014-06-12T11:12:43.029Z"}, "i922lobl3kron3t81pjap31anopkspvb"), + Entry("cbg id", []string{"cbg", "DexHealthKit_Dexcom:com.dexcom.Share2:3.0.4.17", "2015-12-21T11:23:08Z"}, "nsikjhfaprplpq78hc7di2lu5qpt1e3k"), + Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T00:00:00.000Z"}, "kmm427pfbrc6rugtmbuli8j4q61u17uk"), + Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T06:00:00.000Z"}, "cjou7vscvp8ogv34d6vejootulqfn3jd"), + Entry("basal id", []string{"basal", "temp", "tools", "2014-06-11T09:00:00.000Z"}, "tn33bjb0241j9qh4jg9vdnf1g6k1g9r8"), + Entry("basal id", []string{"basal", "scheduled", "tools", "2014-06-11T19:00:00.000Z"}, "kftn188l8rjuvma3qkd3iqg34t0plajp"), ) }) }) diff --git a/data/types/basal/basal.go b/data/types/basal/basal.go index fc5ecc47b0..27b96fa436 100644 --- a/data/types/basal/basal.go +++ b/data/types/basal/basal.go @@ -2,7 +2,6 @@ package basal import ( "github.com/tidepool-org/platform/data/types" - "github.com/tidepool-org/platform/errors" "github.com/tidepool-org/platform/structure" structureValidator "github.com/tidepool-org/platform/structure/validator" ) @@ -51,25 +50,39 @@ func (b *Basal) Validate(validator structure.Validator) { } func (b *Basal) IdentityFields(version string) ([]string, error) { + identityFields := []string{} + var err error if version == types.LegacyIdentityFieldsVersion { - return types.GetLegacyIDFields( - types.LegacyIDField{Name: "type", Value: &b.Type}, - types.LegacyIDField{Name: "delivery type", Value: &b.DeliveryType}, - types.LegacyIDField{Name: "device id", Value: b.DeviceID}, - types.GetLegacyTimeField(b.Time), - ) + + identityFields, err = types.AppendIdentityFieldVal(identityFields, &b.Type, "type") + if err != nil { + return nil, err + } + identityFields, err = types.AppendIdentityFieldVal(identityFields, &b.DeliveryType, "delivery type") + if err != nil { + return nil, err + } + identityFields, err = types.AppendIdentityFieldVal(identityFields, b.DeviceID, "device id") + if err != nil { + return nil, err + } + identityFields, err = types.AppendLegacyTimeVal(identityFields, b.Time) + if err != nil { + return nil, err + } + return identityFields, nil } - identityFields, err := b.Base.IdentityFields(version) + identityFields, err = b.Base.IdentityFields(version) if err != nil { return nil, err } - - if b.DeliveryType == "" { - return nil, errors.New("delivery type is empty") + identityFields, err = types.AppendIdentityFieldVal(identityFields, &b.DeliveryType, "delivery type") + if err != nil { + return nil, err } - return append(identityFields, b.DeliveryType), nil + return identityFields, nil } func ParseDeliveryType(parser structure.ObjectParser) *string { diff --git a/data/types/base.go b/data/types/base.go index d35a67a767..f70877473d 100644 --- a/data/types/base.go +++ b/data/types/base.go @@ -1,7 +1,6 @@ package types import ( - "fmt" "sort" "time" @@ -243,29 +242,33 @@ func (b *Base) Normalize(normalizer data.Normalizer) { } func currentIdentityFields(b *Base) ([]string, error) { - if b.UserID == nil { - return nil, errors.New("user id is missing") - } - if *b.UserID == "" { - return nil, errors.New("user id is empty") - } - if b.DeviceID == nil { - return nil, errors.New("device id is missing") + + vals := []string{} + var err error + vals, err = AppendIdentityFieldVal(vals, b.UserID, "user id") + if err != nil { + return nil, err } - if *b.DeviceID == "" { - return nil, errors.New("device id is empty") + + vals, err = AppendIdentityFieldVal(vals, b.DeviceID, "device id") + if err != nil { + return nil, err } + if b.Time == nil { return nil, errors.New("time is missing") } if (*b.Time).IsZero() { return nil, errors.New("time is empty") } - if b.Type == "" { - return nil, errors.New("type is empty") + vals = append(vals, (*b.Time).Format(TimeFormat)) + + vals, err = AppendIdentityFieldVal(vals, &b.Type, "type") + if err != nil { + return nil, err } - return []string{*b.UserID, *b.DeviceID, (*b.Time).Format(TimeFormat), b.Type}, nil + return vals, nil } func (b *Base) IdentityFields(version string) ([]string, error) { @@ -275,55 +278,43 @@ func (b *Base) IdentityFields(version string) ([]string, error) { return currentIdentityFields(b) } -type LegacyIDField struct { - Value *string - Name string -} - -func GetLegacyTimeField(t *time.Time) LegacyIDField { +func AppendLegacyTimeVal(vals []string, t *time.Time) ([]string, error) { if t == nil { - return LegacyIDField{Name: "time", Value: nil} + return nil, errors.New("time is missing") } - tVal := "" if (*t).IsZero() { - return LegacyIDField{Name: "time", Value: &tVal} + return nil, errors.New("time is empty") } - - tVal = (*t).Format(LegacyTimeFormat) - return LegacyIDField{Name: "time", Value: &tVal} + return append(vals, (*t).Format(LegacyTimeFormat)), nil } -func GetLegacyIDFields(fields ...LegacyIDField) ([]string, error) { - identityFields := []string{} - for _, opt := range fields { - if opt.Value == nil { - return nil, fmt.Errorf("%s is missing", opt.Name) - } - if *opt.Value == "" { - return nil, fmt.Errorf("%s is empty", opt.Name) - } - identityFields = append(identityFields, *opt.Value) +func AppendIdentityFieldVal(vals []string, val *string, errDetail string) ([]string, error) { + if val == nil { + return nil, errors.Newf("%s is missing", errDetail) } - return identityFields, nil + if *val == "" { + return nil, errors.Newf("%s is empty", errDetail) + } + vals = append(vals, *val) + return vals, nil } func legacyIdentityFields(b *Base) ([]string, error) { - if b.Type == "" { - return nil, errors.New("type is empty") - } - if b.DeviceID == nil { - return nil, errors.New("device id is missing") + vals := []string{} + var err error + vals, err = AppendIdentityFieldVal(vals, &b.Type, "type") + if err != nil { + return nil, err } - if *b.DeviceID == "" { - return nil, errors.New("device id is empty") + vals, err = AppendIdentityFieldVal(vals, b.DeviceID, "device id") + if err != nil { + return nil, err } - if b.Time == nil { - return nil, errors.New("time is missing") - } - if (*b.Time).IsZero() { - return nil, errors.New("time is empty") + vals, err = AppendLegacyTimeVal(vals, b.Time) + if err != nil { + return nil, err } - return []string{b.Type, *b.DeviceID, (*b.Time).Format(LegacyTimeFormat)}, nil + return vals, nil } func (b *Base) GetOrigin() *origin.Origin { diff --git a/data/types/base_test.go b/data/types/base_test.go index 9b575d0b18..a623c29995 100644 --- a/data/types/base_test.go +++ b/data/types/base_test.go @@ -989,36 +989,38 @@ var _ = Describe("Base", func() { Expect(legacyIDFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyTimeFormat)})) }) - Context("GetLegacyIDFields", func() { - It("returns error if value is empty", func() { - legacyIDFields, err := types.GetLegacyIDFields(types.LegacyIDField{Name: "first field", Value: pointer.FromString("")}) - Expect(err).To(MatchError("first field is empty")) - Expect(legacyIDFields).To(BeEmpty()) - }) + // Context("GetLegacyIDFields", func() { + // It("returns error if value is empty", func() { + // legacyIDFields, err := types.GetLegacyIDFields(types.LegacyIDField{Name: "first field", Value: pointer.FromString("")}) + // Expect(err).To(MatchError("first field is empty")) + // Expect(legacyIDFields).To(BeEmpty()) + // }) - It("returns legacy id fields if valid", func() { - legacyIDFields, err := types.GetLegacyIDFields(types.LegacyIDField{Name: "first field", Value: pointer.FromString("some-thing")}) - Expect(err).To(BeNil()) - Expect(legacyIDFields).To(Equal([]string{"some-thing"})) - }) + // It("returns legacy id fields if valid", func() { + // legacyIDFields, err := types.GetLegacyIDFields(types.LegacyIDField{Name: "first field", Value: pointer.FromString("some-thing")}) + // Expect(err).To(BeNil()) + // Expect(legacyIDFields).To(Equal([]string{"some-thing"})) + // }) - It("returns legacy id with all fields if valid", func() { - legacyIDFields, err := types.GetLegacyIDFields( - types.LegacyIDField{Name: "first field", Value: pointer.FromString("one")}, - types.LegacyIDField{Name: "second field", Value: pointer.FromString("two")}, - types.LegacyIDField{Name: "third field", Value: pointer.FromString("three")}, - ) - Expect(err).To(BeNil()) - Expect(legacyIDFields).To(Equal([]string{"one", "two", "three"})) - }) - }) + // It("returns legacy id with all fields if valid", func() { + // legacyIDFields, err := types.GetLegacyIDFields( + // types.LegacyIDField{Name: "first field", Value: pointer.FromString("one")}, + // types.LegacyIDField{Name: "second field", Value: pointer.FromString("two")}, + // types.LegacyIDField{Name: "third field", Value: pointer.FromString("three")}, + // ) + // Expect(err).To(BeNil()) + // Expect(legacyIDFields).To(Equal([]string{"one", "two", "three"})) + // }) + // }) Context("GetLegacyTimeField", func() { It("returns expected legacy field details", func() { t, _ := time.Parse(time.RFC3339Nano, "2015-07-31T23:59:59.999Z") - legacyTimeField := types.GetLegacyTimeField(&t) - Expect(legacyTimeField.Name).To(Equal("time")) - Expect(*legacyTimeField.Value).To(Equal("2015-07-31T23:59:59.999Z")) + vals := []string{} + var err error + vals, err = types.AppendLegacyTimeVal(vals, &t) + Expect(err).To(BeNil()) + Expect(vals).To(ContainElement("2015-07-31T23:59:59.999Z")) }) }) }) diff --git a/data/types/bolus/bolus.go b/data/types/bolus/bolus.go index 91d13863e8..2990fa7fc7 100644 --- a/data/types/bolus/bolus.go +++ b/data/types/bolus/bolus.go @@ -4,7 +4,6 @@ import ( "github.com/tidepool-org/platform/data" "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/data/types/insulin" - "github.com/tidepool-org/platform/errors" "github.com/tidepool-org/platform/structure" ) @@ -83,23 +82,41 @@ func (b *Bolus) Normalize(normalizer data.Normalizer) { func (b *Bolus) IdentityFields(version string) ([]string, error) { + identityFields := []string{} + var err error if version == types.LegacyIdentityFieldsVersion { - return types.GetLegacyIDFields( - types.LegacyIDField{Name: "type", Value: &b.Type}, - types.LegacyIDField{Name: "sub type", Value: &b.SubType}, - types.LegacyIDField{Name: "device id", Value: b.DeviceID}, - types.GetLegacyTimeField(b.Time), - ) + + identityFields, err = types.AppendIdentityFieldVal(identityFields, &b.Type, "type") + if err != nil { + return nil, err + } + + identityFields, err = types.AppendIdentityFieldVal(identityFields, &b.SubType, "sub type") + if err != nil { + return nil, err + } + + identityFields, err = types.AppendIdentityFieldVal(identityFields, b.DeviceID, "device id") + if err != nil { + return nil, err + } + + identityFields, err = types.AppendLegacyTimeVal(identityFields, b.Time) + if err != nil { + return nil, err + } + return identityFields, nil } - identityFields, err := b.Base.IdentityFields(version) + identityFields, err = b.Base.IdentityFields(version) if err != nil { return nil, err } - if b.SubType == "" { - return nil, errors.New("sub type is empty") + identityFields, err = types.AppendIdentityFieldVal(identityFields, &b.SubType, "sub type") + if err != nil { + return nil, err } - return append(identityFields, b.SubType), nil + return identityFields, nil } diff --git a/data/types/device/device.go b/data/types/device/device.go index f48a80254b..9b209c7e63 100644 --- a/data/types/device/device.go +++ b/data/types/device/device.go @@ -2,7 +2,6 @@ package device import ( "github.com/tidepool-org/platform/data/types" - "github.com/tidepool-org/platform/errors" "github.com/tidepool-org/platform/structure" ) @@ -46,21 +45,40 @@ func (d *Device) Validate(validator structure.Validator) { } func (d *Device) IdentityFields(version string) ([]string, error) { + identityFields := []string{} + var err error if version == types.LegacyIdentityFieldsVersion { - return types.GetLegacyIDFields( - types.LegacyIDField{Name: "type", Value: &d.Type}, - types.LegacyIDField{Name: "sub type", Value: &d.SubType}, - types.GetLegacyTimeField(d.Time), - types.LegacyIDField{Name: "device id", Value: d.DeviceID}, - ) + + identityFields, err = types.AppendIdentityFieldVal(identityFields, &d.Type, "type") + if err != nil { + return nil, err + } + + identityFields, err = types.AppendIdentityFieldVal(identityFields, &d.SubType, "sub type") + if err != nil { + return nil, err + } + + identityFields, err = types.AppendLegacyTimeVal(identityFields, d.Time) + if err != nil { + return nil, err + } + + identityFields, err = types.AppendIdentityFieldVal(identityFields, d.DeviceID, "device id") + if err != nil { + return nil, err + } + + return identityFields, nil } - identityFields, err := d.Base.IdentityFields(version) + identityFields, err = d.Base.IdentityFields(version) if err != nil { return nil, err } - if d.SubType == "" { - return nil, errors.New("sub type is empty") + identityFields, err = types.AppendIdentityFieldVal(identityFields, &d.SubType, "sub type") + if err != nil { + return nil, err } - return append(identityFields, d.SubType), nil + return identityFields, nil } diff --git a/data/types/settings/cgm/cgm.go b/data/types/settings/cgm/cgm.go index 4049b2a150..abd57a595e 100644 --- a/data/types/settings/cgm/cgm.go +++ b/data/types/settings/cgm/cgm.go @@ -158,12 +158,25 @@ func (c *CGM) Normalize(normalizer data.Normalizer) { } func (c *CGM) IdentityFields(version string) ([]string, error) { + identityFields := []string{} + var err error if version == types.LegacyIdentityFieldsVersion { - return dataTypes.GetLegacyIDFields( - dataTypes.LegacyIDField{Name: "type", Value: &c.Type}, - dataTypes.GetLegacyTimeField(c.Time), - dataTypes.LegacyIDField{Name: "device id", Value: c.DeviceID}, - ) + + identityFields, err = dataTypes.AppendIdentityFieldVal(identityFields, &c.Type, "type") + if err != nil { + return nil, err + } + + identityFields, err = dataTypes.AppendLegacyTimeVal(identityFields, c.Time) + if err != nil { + return nil, err + } + + identityFields, err = dataTypes.AppendIdentityFieldVal(identityFields, c.DeviceID, "device id") + if err != nil { + return nil, err + } + return identityFields, nil } return c.Base.IdentityFields(version) } From 1c6731fccc514f29af3b5ae46b9ece6444f89772 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 23 Oct 2024 09:38:09 +1300 Subject: [PATCH 405/413] review updates --- .../deduplicator/device_deactivate_hash.go | 5 ++-- data/deduplicator/deduplicator/hash.go | 4 ++- data/types/base_test.go | 29 ++----------------- data/types/blood/test/blood.go | 2 ++ 4 files changed, 11 insertions(+), 29 deletions(-) diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index c119a7ed94..303b60b1e0 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -156,9 +156,10 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore return errors.Wrap(err, "error getting datasets for user") } if len(uploads) != 0 { - if uploads[0].LegacyGroupID != nil { - options = NewLegacyHashOptions(*uploads[0].LegacyGroupID) + if uploads[0].LegacyGroupID == nil { + return missingLegacyGroupIdErr } + options = NewLegacyHashOptions(*uploads[0].LegacyGroupID) } } diff --git a/data/deduplicator/deduplicator/hash.go b/data/deduplicator/deduplicator/hash.go index c9d5afeb35..18c55b31f3 100644 --- a/data/deduplicator/deduplicator/hash.go +++ b/data/deduplicator/deduplicator/hash.go @@ -31,12 +31,14 @@ func NewDefaultDeviceDeactivateHashOptions() HashOptions { } } +var missingLegacyGroupIdErr = errors.New("missing required legacy groupId for the device deactive hash legacy version") + func (d HashOptions) Validate() error { switch d.Version { case DeviceDeactivateHashVersionLegacy: if d.LegacyGroupID == nil || *d.LegacyGroupID == "" { - return errors.New("missing required legacy groupId for the device deactive hash legacy version") + return missingLegacyGroupIdErr } case DeviceDeactivateHashVersionCurrent: break diff --git a/data/types/base_test.go b/data/types/base_test.go index a623c29995..c54ec05931 100644 --- a/data/types/base_test.go +++ b/data/types/base_test.go @@ -989,37 +989,14 @@ var _ = Describe("Base", func() { Expect(legacyIDFields).To(Equal([]string{datum.Type, *datum.DeviceID, (*datum.Time).Format(types.LegacyTimeFormat)})) }) - // Context("GetLegacyIDFields", func() { - // It("returns error if value is empty", func() { - // legacyIDFields, err := types.GetLegacyIDFields(types.LegacyIDField{Name: "first field", Value: pointer.FromString("")}) - // Expect(err).To(MatchError("first field is empty")) - // Expect(legacyIDFields).To(BeEmpty()) - // }) - - // It("returns legacy id fields if valid", func() { - // legacyIDFields, err := types.GetLegacyIDFields(types.LegacyIDField{Name: "first field", Value: pointer.FromString("some-thing")}) - // Expect(err).To(BeNil()) - // Expect(legacyIDFields).To(Equal([]string{"some-thing"})) - // }) - - // It("returns legacy id with all fields if valid", func() { - // legacyIDFields, err := types.GetLegacyIDFields( - // types.LegacyIDField{Name: "first field", Value: pointer.FromString("one")}, - // types.LegacyIDField{Name: "second field", Value: pointer.FromString("two")}, - // types.LegacyIDField{Name: "third field", Value: pointer.FromString("three")}, - // ) - // Expect(err).To(BeNil()) - // Expect(legacyIDFields).To(Equal([]string{"one", "two", "three"})) - // }) - // }) - - Context("GetLegacyTimeField", func() { - It("returns expected legacy field details", func() { + Context("AppendLegacyTimeVal", func() { + It("returns expected time in legacy time format", func() { t, _ := time.Parse(time.RFC3339Nano, "2015-07-31T23:59:59.999Z") vals := []string{} var err error vals, err = types.AppendLegacyTimeVal(vals, &t) Expect(err).To(BeNil()) + Expect(len(vals)).To(Equal(1)) Expect(vals).To(ContainElement("2015-07-31T23:59:59.999Z")) }) }) diff --git a/data/types/blood/test/blood.go b/data/types/blood/test/blood.go index cdb972a854..601c1779b8 100644 --- a/data/types/blood/test/blood.go +++ b/data/types/blood/test/blood.go @@ -5,6 +5,7 @@ import ( "github.com/tidepool-org/platform/data/types/blood" dataTypesTest "github.com/tidepool-org/platform/data/types/test" + "github.com/tidepool-org/platform/metadata" metadataTest "github.com/tidepool-org/platform/metadata/test" "github.com/tidepool-org/platform/pointer" "github.com/tidepool-org/platform/test" @@ -15,6 +16,7 @@ func NewBlood() *blood.Blood { datum.Base = *dataTypesTest.RandomBase() datum.Units = pointer.FromString(dataTypesTest.NewType()) datum.Value = pointer.FromFloat64(test.RandomFloat64FromRange(-math.MaxFloat64, math.MaxFloat64)) + datum.Raw = &metadata.Metadata{"units": datum.Units, "value": datum.Value} return datum } From 6d84df2d0b42f896ac114c6fe26f42b6cef9f402 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 30 Oct 2024 14:17:18 +1300 Subject: [PATCH 406/413] updates from merge --- .../deduplicator/device_deactivate_hash_test.go | 6 +++--- data/deduplicator/deduplicator/hash_test.go | 3 ++- data/types/settings/pump/bolus_test.go | 2 +- data/types/settings/pump/sleep_schedule_test.go | 5 +++-- dexcom/fetch/translate.go | 3 +-- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/data/deduplicator/deduplicator/device_deactivate_hash_test.go b/data/deduplicator/deduplicator/device_deactivate_hash_test.go index 553021188b..44eb307ea6 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash_test.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash_test.go @@ -66,14 +66,14 @@ var _ = Describe("DeviceDeactivateHash", func() { It("returns false when the deduplicator name does not match", func() { dataSet.Deduplicator.Name = pointer.FromString(netTest.RandomReverseDomain()) - Expect(deduplicator.New(dataSet)).To(BeFalse()) + Expect(deduplicator.New(context.Background(), dataSet)).To(BeFalse()) }) DescribeTable("returns true when", func(deviceManufacturer string, deviceModel string) { dataSet.DeviceManufacturers = pointer.FromStringArray([]string{deviceManufacturer}) dataSet.DeviceModel = pointer.FromString(deviceModel) - Expect(deduplicator.New(dataSet)).To(BeTrue()) + Expect(deduplicator.New(context.Background(), dataSet)).To(BeTrue()) }, Entry("is Abbott FreeStyle Libre", "Abbott", "FreeStyle Libre"), Entry("is LifeScan OneTouch Ultra 2", "LifeScan", "OneTouch Ultra 2"), @@ -264,7 +264,7 @@ var _ = Describe("DeviceDeactivateHash", func() { dataSet.Deduplicator.Name = pointer.FromString(dataDeduplicatorDeduplicator.DeviceDeactivateHashName) dataSet.DeviceManufacturers = pointer.FromStringArray([]string{"Tandem"}) dataSet.DeviceModel = pointer.FromString("1002717") - Expect(deduplicator.Get(dataSet)).To(BeTrue()) + Expect(deduplicator.Get(context.Background(), dataSet)).To(BeTrue()) }) }) diff --git a/data/deduplicator/deduplicator/hash_test.go b/data/deduplicator/deduplicator/hash_test.go index 01ba7ef3f1..af833b2c26 100644 --- a/data/deduplicator/deduplicator/hash_test.go +++ b/data/deduplicator/deduplicator/hash_test.go @@ -11,6 +11,7 @@ import ( "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" dataTypesBloodGlucoseTest "github.com/tidepool-org/platform/data/types/blood/glucose/test" "github.com/tidepool-org/platform/errors" + logTest "github.com/tidepool-org/platform/log/test" "github.com/tidepool-org/platform/pointer" "github.com/tidepool-org/platform/structure" "github.com/tidepool-org/platform/test" @@ -162,7 +163,7 @@ var _ = Describe("Hash", func() { datum.Value = pointer.FromFloat64(150) datum.SubType = pointer.FromString(test.RandomStringFromArray(selfmonitored.SubTypes())) - normalizer := dataNormalizer.New() + normalizer := dataNormalizer.New(logTest.NewLogger()) Expect(normalizer).ToNot(BeNil()) datum.Normalize(normalizer.WithOrigin(structure.OriginExternal)) return datum diff --git a/data/types/settings/pump/bolus_test.go b/data/types/settings/pump/bolus_test.go index 868e123661..546f280ca2 100644 --- a/data/types/settings/pump/bolus_test.go +++ b/data/types/settings/pump/bolus_test.go @@ -161,7 +161,7 @@ var _ = Describe("Bolus", func() { datum := pumpTest.NewRandomBolusMap(1, 4) mutator(datum) expectedDatum := pumpTest.CloneBolusMap(datum) - normalizer := dataNormalizer.New() + normalizer := dataNormalizer.New(logTest.NewLogger()) Expect(normalizer).ToNot(BeNil()) datum.Normalize(normalizer.WithOrigin(origin)) Expect(normalizer.Error()).To(BeNil()) diff --git a/data/types/settings/pump/sleep_schedule_test.go b/data/types/settings/pump/sleep_schedule_test.go index 2903a86fda..f63bc026bc 100644 --- a/data/types/settings/pump/sleep_schedule_test.go +++ b/data/types/settings/pump/sleep_schedule_test.go @@ -10,6 +10,7 @@ import ( dataTypesSettingsPump "github.com/tidepool-org/platform/data/types/settings/pump" dataTypesSettingsPumpTest "github.com/tidepool-org/platform/data/types/settings/pump/test" errorsTest "github.com/tidepool-org/platform/errors/test" + logTest "github.com/tidepool-org/platform/log/test" "github.com/tidepool-org/platform/pointer" structureValidator "github.com/tidepool-org/platform/structure/validator" "github.com/tidepool-org/platform/test" @@ -32,7 +33,7 @@ var _ = Describe("SleepSchedule", func() { func(mutator func(datum *dataTypesSettingsPump.SleepScheduleMap), expectedErrors ...error) { datum := dataTypesSettingsPumpTest.RandomSleepScheduleMap(3) mutator(datum) - errorsTest.ExpectEqual(structureValidator.New().Validate(datum), expectedErrors...) + errorsTest.ExpectEqual(structureValidator.New(logTest.NewLogger()).Validate(datum), expectedErrors...) }, Entry("succeeds", func(datum *dataTypesSettingsPump.SleepScheduleMap) {}, @@ -101,7 +102,7 @@ var _ = Describe("SleepSchedule", func() { func(mutator func(datum *dataTypesSettingsPump.SleepSchedule) []error) { datum := dataTypesSettingsPumpTest.RandomSleepSchedule() expectedErrors := mutator(datum) - errorsTest.ExpectEqual(structureValidator.New().Validate(datum), expectedErrors...) + errorsTest.ExpectEqual(structureValidator.New(logTest.NewLogger()).Validate(datum), expectedErrors...) }, Entry("succeeds", func(datum *dataTypesSettingsPump.SleepSchedule) []error { return nil }, diff --git a/dexcom/fetch/translate.go b/dexcom/fetch/translate.go index 5175f8c50c..d373a5857e 100644 --- a/dexcom/fetch/translate.go +++ b/dexcom/fetch/translate.go @@ -10,11 +10,10 @@ import ( dataBloodGlucose "github.com/tidepool-org/platform/data/blood/glucose" dataTypes "github.com/tidepool-org/platform/data/types" dataTypesActivityPhysical "github.com/tidepool-org/platform/data/types/activity/physical" - "github.com/tidepool-org/platform/data/types/common" - dataTypesAlert "github.com/tidepool-org/platform/data/types/alert" dataTypesBloodGlucoseContinuous "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" dataTypesBloodGlucoseSelfMonitored "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" + "github.com/tidepool-org/platform/data/types/common" dataTypesDeviceCalibration "github.com/tidepool-org/platform/data/types/device/calibration" dataTypesFood "github.com/tidepool-org/platform/data/types/food" dataTypesInsulin "github.com/tidepool-org/platform/data/types/insulin" From adbd24f858058e31087e148f0d22c810fb8dfd11 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 11 Nov 2024 16:22:52 +1300 Subject: [PATCH 407/413] review updates --- data/deduplicator/deduplicator/base.go | 2 -- .../deduplicator/device_deactivate_hash.go | 14 ++++++++------ data/deduplicator/deduplicator/hash.go | 8 ++++---- data/store/mongo/mongo_data_set.go | 8 ++------ data/types/bolus/bolus.go | 6 ++---- data/types/bolus/bolus_test.go | 2 +- data/types/bolus/test/bolus.go | 2 +- 7 files changed, 18 insertions(+), 24 deletions(-) diff --git a/data/deduplicator/deduplicator/base.go b/data/deduplicator/deduplicator/base.go index 19ad2ae6df..daed7f31e3 100644 --- a/data/deduplicator/deduplicator/base.go +++ b/data/deduplicator/deduplicator/base.go @@ -24,8 +24,6 @@ func NewBase(name string, version string) (*Base, error) { } if version == "" { return nil, errors.New("version is missing") - } else if !net.IsValidSemanticVersion(version) { - return nil, errors.New("version is invalid") } return &Base{ diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index d25c962547..8bc5d75d50 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -13,9 +13,9 @@ import ( ) const ( - DeviceDeactivateHashVersionUnknown string = "" - DeviceDeactivateHashVersionCurrent string = types.IdentityFieldsVersion - DeviceDeactivateHashVersionLegacy string = types.LegacyIdentityFieldsVersion + DeviceDeactivateHashVersionUnknown = "unknown-hash" + DeviceDeactivateHashVersionLegacy = "legacy-hash" + DeviceDeactivateHashVersionCurrent = "current-hash" ) const DeviceDeactivateHashName = "org.tidepool.deduplicator.device.deactivate.hash" @@ -70,8 +70,10 @@ func getDeduplicatorVersion(dataSet *dataTypesUpload.Upload) string { if dataSet.Deduplicator != nil { if dataSet.Deduplicator.Name != nil && dataSet.Deduplicator.Version != nil { if *dataSet.Deduplicator.Name == DeviceDeactivateHashName { - if *dataSet.Deduplicator.Version != "" { - return *dataSet.Deduplicator.Version + if types.LegacyIdentityFieldsVersion == *dataSet.Deduplicator.Version { + return DeviceDeactivateHashVersionLegacy + } else if types.IdentityFieldsVersion == *dataSet.Deduplicator.Version { + return DeviceDeactivateHashVersionCurrent } } } @@ -157,7 +159,7 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore } if len(uploads) != 0 { if uploads[0].LegacyGroupID == nil { - return missingLegacyGroupIdErr + return errors.New("missing required legacy groupId for the device deactive hash legacy version") } options = NewLegacyHashOptions(*uploads[0].LegacyGroupID) } diff --git a/data/deduplicator/deduplicator/hash.go b/data/deduplicator/deduplicator/hash.go index 18c55b31f3..addb60117c 100644 --- a/data/deduplicator/deduplicator/hash.go +++ b/data/deduplicator/deduplicator/hash.go @@ -31,17 +31,17 @@ func NewDefaultDeviceDeactivateHashOptions() HashOptions { } } -var missingLegacyGroupIdErr = errors.New("missing required legacy groupId for the device deactive hash legacy version") - func (d HashOptions) Validate() error { switch d.Version { case DeviceDeactivateHashVersionLegacy: if d.LegacyGroupID == nil || *d.LegacyGroupID == "" { - return missingLegacyGroupIdErr + return errors.New("missing required legacy groupId for the device deactive hash legacy version") } case DeviceDeactivateHashVersionCurrent: - break + if d.LegacyGroupID != nil || *d.LegacyGroupID != "" { + return errors.New("groupId is not required for the device deactive hash current version") + } default: return errors.Newf("missing valid version %s", d.Version) } diff --git a/data/store/mongo/mongo_data_set.go b/data/store/mongo/mongo_data_set.go index db1a3b1abb..b59fb4138e 100644 --- a/data/store/mongo/mongo_data_set.go +++ b/data/store/mongo/mongo_data_set.go @@ -278,12 +278,8 @@ func (d *DataSetRepository) ListUserDataSets(ctx context.Context, userID string, if filter.DeviceID != nil { selector["deviceId"] = *filter.DeviceID } - if filter.LegacyOnly != nil { - if *filter.LegacyOnly { - selector["_id"] = bson.M{"$not": bson.M{"$type": "objectId"}} - } else { - selector["_id"] = bson.M{"$type": "objectId"} - } + if filter.LegacyOnly != nil && *filter.LegacyOnly { + selector["_id"] = bson.M{"$not": bson.M{"$type": "objectId"}} } opts := storeStructuredMongo.FindWithPagination(pagination). diff --git a/data/types/bolus/bolus.go b/data/types/bolus/bolus.go index 2990fa7fc7..78ffb03248 100644 --- a/data/types/bolus/bolus.go +++ b/data/types/bolus/bolus.go @@ -30,7 +30,7 @@ type Meta struct { SubType string `json:"subType,omitempty"` } -func DeliveryContext() []string { +func DeliveryContexts() []string { return []string{DeliveryContextDevice, DeliveryContextAlgorithm, DeliveryContextRemote, DeliveryContextUndetermined} } @@ -67,9 +67,7 @@ func (b *Bolus) Validate(validator structure.Validator) { b.InsulinFormulation.Validate(validator.WithReference("insulinFormulation")) } - if b.DeliveryContext != nil { - validator.String("deliveryContext", b.DeliveryContext).Exists().OneOf(DeliveryContext()...) - } + validator.String("deliveryContext", b.DeliveryContext).OneOf(DeliveryContexts()...) } func (b *Bolus) Normalize(normalizer data.Normalizer) { diff --git a/data/types/bolus/bolus_test.go b/data/types/bolus/bolus_test.go index f6bbc237f7..21c998c168 100644 --- a/data/types/bolus/bolus_test.go +++ b/data/types/bolus/bolus_test.go @@ -92,7 +92,7 @@ var _ = Describe("Bolus", func() { ), Entry("delivery context invalid", func(datum *bolus.Bolus) { datum.DeliveryContext = pointer.FromString("invalid") }, - errorsTest.WithPointerSource(structureValidator.ErrorValueStringNotOneOf("invalid", bolus.DeliveryContext()), "/deliveryContext"), + errorsTest.WithPointerSource(structureValidator.ErrorValueStringNotOneOf("invalid", bolus.DeliveryContexts()), "/deliveryContext"), ), Entry("delivery context valid", func(datum *bolus.Bolus) { datum.DeliveryContext = pointer.FromString(bolus.DeliveryContextAlgorithm) }, diff --git a/data/types/bolus/test/bolus.go b/data/types/bolus/test/bolus.go index 7f1f95c5ef..0ae9da6e15 100644 --- a/data/types/bolus/test/bolus.go +++ b/data/types/bolus/test/bolus.go @@ -26,7 +26,7 @@ func randomBolus() *dataTypesBolus.Bolus { datum := &dataTypesBolus.Bolus{} datum.SubType = dataTypesTest.NewType() datum.InsulinFormulation = dataTypesInsulinTest.RandomFormulation(3) - datum.DeliveryContext = pointer.FromString(test.RandomStringFromArray(dataTypesBolus.DeliveryContext())) + datum.DeliveryContext = pointer.FromString(test.RandomStringFromArray(dataTypesBolus.DeliveryContexts())) return datum } From 1a090b040a9d804dce14950476261a023c80bc2e Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 11 Nov 2024 16:37:33 +1300 Subject: [PATCH 408/413] update import for consistency --- dexcom/fetch/translate.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dexcom/fetch/translate.go b/dexcom/fetch/translate.go index d373a5857e..476a256245 100644 --- a/dexcom/fetch/translate.go +++ b/dexcom/fetch/translate.go @@ -13,7 +13,7 @@ import ( dataTypesAlert "github.com/tidepool-org/platform/data/types/alert" dataTypesBloodGlucoseContinuous "github.com/tidepool-org/platform/data/types/blood/glucose/continuous" dataTypesBloodGlucoseSelfMonitored "github.com/tidepool-org/platform/data/types/blood/glucose/selfmonitored" - "github.com/tidepool-org/platform/data/types/common" + dataTypesCommon "github.com/tidepool-org/platform/data/types/common" dataTypesDeviceCalibration "github.com/tidepool-org/platform/data/types/device/calibration" dataTypesFood "github.com/tidepool-org/platform/data/types/food" dataTypesInsulin "github.com/tidepool-org/platform/data/types/insulin" @@ -229,19 +229,19 @@ func translateAlertScheduleSettingsDaysOfWeekToScheduledAlertDays(daysOfWeek *[] func translateAlertScheduleSettingsDayOfWeekToScheduledAlertDay(dayOfWeek string) string { switch dayOfWeek { case dexcom.AlertScheduleSettingsDaySunday: - return common.DaySunday + return dataTypesCommon.DaySunday case dexcom.AlertScheduleSettingsDayMonday: - return common.DayMonday + return dataTypesCommon.DayMonday case dexcom.AlertScheduleSettingsDayTuesday: - return common.DayTuesday + return dataTypesCommon.DayTuesday case dexcom.AlertScheduleSettingsDayWednesday: - return common.DayWednesday + return dataTypesCommon.DayWednesday case dexcom.AlertScheduleSettingsDayThursday: - return common.DayThursday + return dataTypesCommon.DayThursday case dexcom.AlertScheduleSettingsDayFriday: - return common.DayFriday + return dataTypesCommon.DayFriday case dexcom.AlertScheduleSettingsDaySaturday: - return common.DaySaturday + return dataTypesCommon.DaySaturday } return "" } From f7151531ff762653fca9c6fabd11557a00741c36 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 12 Nov 2024 12:50:35 +1300 Subject: [PATCH 409/413] test updates --- data/deduplicator/deduplicator/base_test.go | 12 ++++-------- .../deduplicator/device_deactivate_hash_test.go | 14 +++++++++++++- data/deduplicator/deduplicator/hash.go | 2 +- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/data/deduplicator/deduplicator/base_test.go b/data/deduplicator/deduplicator/base_test.go index f0e1499063..e9da3eaa7f 100644 --- a/data/deduplicator/deduplicator/base_test.go +++ b/data/deduplicator/deduplicator/base_test.go @@ -25,7 +25,10 @@ var _ = Describe("Base", func() { BeforeEach(func() { name = netTest.RandomReverseDomain() - version = netTest.RandomSemanticVersion() + version = test.RandomStringFromArray([]string{ + dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent, + dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy, + }) }) Context("NewBase", func() { @@ -50,13 +53,6 @@ var _ = Describe("Base", func() { Expect(deduplicator).To(BeNil()) }) - It("returns an error when version is invalid", func() { - version = "invalid" - deduplicator, err := dataDeduplicatorDeduplicator.NewBase(name, version) - Expect(err).To(MatchError("version is invalid")) - Expect(deduplicator).To(BeNil()) - }) - It("returns successfully", func() { Expect(dataDeduplicatorDeduplicator.NewBase(name, version)).ToNot(BeNil()) }) diff --git a/data/deduplicator/deduplicator/device_deactivate_hash_test.go b/data/deduplicator/deduplicator/device_deactivate_hash_test.go index 44eb307ea6..643d615809 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash_test.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash_test.go @@ -25,6 +25,18 @@ var _ = Describe("DeviceDeactivateHash", func() { Expect(dataDeduplicatorDeduplicator.DeviceDeactivateHashName).To(Equal("org.tidepool.deduplicator.device.deactivate.hash")) }) + It("DeviceDeactivateHashVersionCurrent is current-hash", func() { + Expect(dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent).To(Equal("current-hash")) + }) + + It("DeviceDeactivateHashVersionLegacy is legacy-hash", func() { + Expect(dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy).To(Equal("legacy-hash")) + }) + + It("DeviceDeactivateHashVersionUnknown is unkown-hash", func() { + Expect(dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionUnknown).To(Equal("unknown-hash")) + }) + Context("NewDeviceDeactivateHash", func() { It("returns succesfully", func() { Expect(dataDeduplicatorDeduplicator.NewDeviceDeactivateHash()).ToNot(BeNil()) @@ -308,7 +320,7 @@ var _ = Describe("DeviceDeactivateHash", func() { update.Active = pointer.FromBool(false) update.Deduplicator = &data.DeduplicatorDescriptor{ Name: pointer.FromString("org.tidepool.deduplicator.device.deactivate.hash"), - Version: pointer.FromString("1.1.0"), + Version: pointer.FromString(dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent), } }) diff --git a/data/deduplicator/deduplicator/hash.go b/data/deduplicator/deduplicator/hash.go index addb60117c..37cbc2268c 100644 --- a/data/deduplicator/deduplicator/hash.go +++ b/data/deduplicator/deduplicator/hash.go @@ -39,7 +39,7 @@ func (d HashOptions) Validate() error { return errors.New("missing required legacy groupId for the device deactive hash legacy version") } case DeviceDeactivateHashVersionCurrent: - if d.LegacyGroupID != nil || *d.LegacyGroupID != "" { + if d.LegacyGroupID != nil { return errors.New("groupId is not required for the device deactive hash current version") } default: From 7a80fe5f3c0c7f35130a353531d738f0650407fd Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 5 Dec 2024 22:16:24 +1300 Subject: [PATCH 410/413] hash version and identity version --- data/datum.go | 2 +- .../deduplicator/device_deactivate_hash.go | 43 ++++++++++++------- .../device_deactivate_hash_test.go | 12 ++---- data/deduplicator/deduplicator/hash.go | 15 ++++--- data/test/datum.go | 4 +- data/types/activity/physical/physical.go | 2 +- data/types/basal/basal.go | 2 +- data/types/base.go | 31 +++++++------ data/types/base_test.go | 2 +- data/types/blood/blood.go | 2 +- data/types/blood/blood_test.go | 2 +- .../glucose/selfmonitored/selfmonitored.go | 2 +- data/types/bolus/bolus.go | 2 +- data/types/calculator/calculator.go | 2 +- data/types/device/device.go | 2 +- data/types/device/device_test.go | 3 +- data/types/food/food.go | 2 +- data/types/insulin/insulin.go | 2 +- data/types/settings/cgm/cgm.go | 2 +- 19 files changed, 72 insertions(+), 62 deletions(-) diff --git a/data/datum.go b/data/datum.go index 75a34c07de..f00868e495 100644 --- a/data/datum.go +++ b/data/datum.go @@ -15,7 +15,7 @@ type Datum interface { Validate(validator structure.Validator) Normalize(normalizer Normalizer) - IdentityFields(version string) ([]string, error) + IdentityFields(version int) ([]string, error) GetOrigin() *origin.Origin GetPayload() *metadata.Metadata diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index 8bc5d75d50..38bfec3b2e 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -5,7 +5,6 @@ import ( "github.com/tidepool-org/platform/data" dataStore "github.com/tidepool-org/platform/data/store" - "github.com/tidepool-org/platform/data/types" dataTypesUpload "github.com/tidepool-org/platform/data/types/upload" "github.com/tidepool-org/platform/errors" "github.com/tidepool-org/platform/page" @@ -13,9 +12,11 @@ import ( ) const ( - DeviceDeactivateHashVersionUnknown = "unknown-hash" - DeviceDeactivateHashVersionLegacy = "legacy-hash" - DeviceDeactivateHashVersionCurrent = "current-hash" + + // LegacyIdentityFieldsVersion = "0.0.0" + // IdentityFieldsVersion = "1.1.0" + DeviceDeactivateHashVersionLegacy = "0.0.0" + DeviceDeactivateHashVersionCurrent = "1.1.0" ) const DeviceDeactivateHashName = "org.tidepool.deduplicator.device.deactivate.hash" @@ -66,14 +67,14 @@ func NewDeviceDeactivateHash() (*DeviceDeactivateHash, error) { }, nil } -func getDeduplicatorVersion(dataSet *dataTypesUpload.Upload) string { +func getDeduplicatorVersion(dataSet *dataTypesUpload.Upload) (string, error) { if dataSet.Deduplicator != nil { if dataSet.Deduplicator.Name != nil && dataSet.Deduplicator.Version != nil { if *dataSet.Deduplicator.Name == DeviceDeactivateHashName { - if types.LegacyIdentityFieldsVersion == *dataSet.Deduplicator.Version { - return DeviceDeactivateHashVersionLegacy - } else if types.IdentityFieldsVersion == *dataSet.Deduplicator.Version { - return DeviceDeactivateHashVersionCurrent + if *dataSet.Deduplicator.Version == DeviceDeactivateHashVersionLegacy { + return DeviceDeactivateHashVersionLegacy, nil + } else if *dataSet.Deduplicator.Version == DeviceDeactivateHashVersionCurrent { + return DeviceDeactivateHashVersionCurrent, nil } } } @@ -83,7 +84,7 @@ func getDeduplicatorVersion(dataSet *dataTypesUpload.Upload) string { if allowedDeviceModels, found := DeviceDeactivateLegacyHashManufacturerDeviceModels[deviceManufacturer]; found { for _, allowedDeviceModel := range allowedDeviceModels { if allowedDeviceModel == *dataSet.DeviceModel { - return DeviceDeactivateHashVersionLegacy + return DeviceDeactivateHashVersionLegacy, nil } } } @@ -92,13 +93,13 @@ func getDeduplicatorVersion(dataSet *dataTypesUpload.Upload) string { if allowedDeviceModels, found := DeviceDeactivateHashDeviceManufacturerDeviceModels[deviceManufacturer]; found { for _, allowedDeviceModel := range allowedDeviceModels { if allowedDeviceModel == *dataSet.DeviceModel { - return DeviceDeactivateHashVersionCurrent + return DeviceDeactivateHashVersionCurrent, nil } } } } } - return DeviceDeactivateHashVersionUnknown + return "", errors.New("no valid device deactivate hash version") } func (d *DeviceDeactivateHash) New(ctx context.Context, dataSet *dataTypesUpload.Upload) (bool, error) { @@ -114,7 +115,9 @@ func (d *DeviceDeactivateHash) New(ctx context.Context, dataSet *dataTypesUpload if dataSet.HasDeduplicatorName() { return d.Get(ctx, dataSet) } - return getDeduplicatorVersion(dataSet) != DeviceDeactivateHashVersionUnknown, nil + + _, err := getDeduplicatorVersion(dataSet) + return err == nil, nil } func (d *DeviceDeactivateHash) Get(ctx context.Context, dataSet *dataTypesUpload.Upload) (bool, error) { @@ -123,7 +126,12 @@ func (d *DeviceDeactivateHash) Get(ctx context.Context, dataSet *dataTypesUpload return false, errors.New("data set is missing") } - if getDeduplicatorVersion(dataSet) == DeviceDeactivateHashVersionLegacy { + version, err := getDeduplicatorVersion(dataSet) + if err != nil { + return false, err + } + + if version == DeviceDeactivateHashVersionLegacy { return true, nil } @@ -149,7 +157,12 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore options := NewDefaultDeviceDeactivateHashOptions() - if getDeduplicatorVersion(dataSet) == DeviceDeactivateHashVersionLegacy { + version, err := getDeduplicatorVersion(dataSet) + if err != nil { + return err + } + + if version == DeviceDeactivateHashVersionLegacy { filter := &data.DataSetFilter{LegacyOnly: pointer.FromBool(true), DeviceID: dataSet.DeviceID} pagination := &page.Pagination{Page: 1, Size: 1} diff --git a/data/deduplicator/deduplicator/device_deactivate_hash_test.go b/data/deduplicator/deduplicator/device_deactivate_hash_test.go index 643d615809..c89b00fb26 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash_test.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash_test.go @@ -25,16 +25,12 @@ var _ = Describe("DeviceDeactivateHash", func() { Expect(dataDeduplicatorDeduplicator.DeviceDeactivateHashName).To(Equal("org.tidepool.deduplicator.device.deactivate.hash")) }) - It("DeviceDeactivateHashVersionCurrent is current-hash", func() { - Expect(dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent).To(Equal("current-hash")) + It("DeviceDeactivateHashVersionCurrent is 1.1.0", func() { + Expect(dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent).To(Equal("1.1.0")) }) - It("DeviceDeactivateHashVersionLegacy is legacy-hash", func() { - Expect(dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy).To(Equal("legacy-hash")) - }) - - It("DeviceDeactivateHashVersionUnknown is unkown-hash", func() { - Expect(dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionUnknown).To(Equal("unknown-hash")) + It("DeviceDeactivateHashVersionLegacy is 0.0.0", func() { + Expect(dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy).To(Equal("0.0.0")) }) Context("NewDeviceDeactivateHash", func() { diff --git a/data/deduplicator/deduplicator/hash.go b/data/deduplicator/deduplicator/hash.go index 37cbc2268c..f38a557469 100644 --- a/data/deduplicator/deduplicator/hash.go +++ b/data/deduplicator/deduplicator/hash.go @@ -9,41 +9,42 @@ import ( "strings" "github.com/tidepool-org/platform/data" + "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/errors" "github.com/tidepool-org/platform/pointer" ) type HashOptions struct { - Version string + Version int LegacyGroupID *string } func NewLegacyHashOptions(legacyGroupID string) HashOptions { return HashOptions{ - Version: DeviceDeactivateHashVersionLegacy, + Version: types.LegacyIdentityFieldsVersion, LegacyGroupID: &legacyGroupID, } } func NewDefaultDeviceDeactivateHashOptions() HashOptions { return HashOptions{ - Version: DeviceDeactivateHashVersionCurrent, + Version: types.IdentityFieldsVersion, } } func (d HashOptions) Validate() error { switch d.Version { - case DeviceDeactivateHashVersionLegacy: + case types.LegacyIdentityFieldsVersion: if d.LegacyGroupID == nil || *d.LegacyGroupID == "" { return errors.New("missing required legacy groupId for the device deactive hash legacy version") } - case DeviceDeactivateHashVersionCurrent: + case types.IdentityFieldsVersion: if d.LegacyGroupID != nil { return errors.New("groupId is not required for the device deactive hash current version") } default: - return errors.Newf("missing valid version %s", d.Version) + return errors.Newf("missing valid version %d", d.Version) } return nil } @@ -60,7 +61,7 @@ func AssignDataSetDataIdentityHashes(dataSetData data.Data, options HashOptions) return errors.Wrap(err, "unable to gather identity fields for datum") } - if options.Version == DeviceDeactivateHashVersionLegacy { + if options.Version == types.LegacyIdentityFieldsVersion { hash, err = GenerateLegacyIdentityHash(fields) if err != nil { return errors.Wrapf(err, "unable to generate legacy identity hash for datum %T", dataSetDatum) diff --git a/data/test/datum.go b/data/test/datum.go index c5744946d1..a1b49a3173 100644 --- a/data/test/datum.go +++ b/data/test/datum.go @@ -27,7 +27,7 @@ type Datum struct { NormalizeInvocations int NormalizeInputs []data.Normalizer IdentityFieldsInvocations int - IdentityFieldsInputs []string + IdentityFieldsInputs []int IdentityFieldsOutputs []IdentityFieldsOutput GetPayloadInvocations int GetPayloadOutputs []*metadata.Metadata @@ -104,7 +104,7 @@ func (d *Datum) Normalize(normalizer data.Normalizer) { d.NormalizeInputs = append(d.NormalizeInputs, normalizer) } -func (d *Datum) IdentityFields(version string) ([]string, error) { +func (d *Datum) IdentityFields(version int) ([]string, error) { d.IdentityFieldsInvocations++ d.IdentityFieldsInputs = append(d.IdentityFieldsInputs, version) diff --git a/data/types/activity/physical/physical.go b/data/types/activity/physical/physical.go index db1f9717ca..4bd297dcdc 100644 --- a/data/types/activity/physical/physical.go +++ b/data/types/activity/physical/physical.go @@ -297,6 +297,6 @@ func (p *Physical) Normalize(normalizer data.Normalizer) { } } -func (p *Physical) IdentityFields(version string) ([]string, error) { +func (p *Physical) IdentityFields(version int) ([]string, error) { return p.Base.IdentityFields(version) } diff --git a/data/types/basal/basal.go b/data/types/basal/basal.go index 27b96fa436..f746d764fd 100644 --- a/data/types/basal/basal.go +++ b/data/types/basal/basal.go @@ -49,7 +49,7 @@ func (b *Basal) Validate(validator structure.Validator) { validator.String("deliveryType", &b.DeliveryType).Exists().NotEmpty() } -func (b *Basal) IdentityFields(version string) ([]string, error) { +func (b *Basal) IdentityFields(version int) ([]string, error) { identityFields := []string{} var err error if version == types.LegacyIdentityFieldsVersion { diff --git a/data/types/base.go b/data/types/base.go index f70877473d..20b555ccf8 100644 --- a/data/types/base.go +++ b/data/types/base.go @@ -17,21 +17,20 @@ import ( ) const ( - ClockDriftOffsetMaximum = 24 * 60 * 60 * 1000 // TODO: Fix! Limit to reasonable values - ClockDriftOffsetMinimum = -24 * 60 * 60 * 1000 // TODO: Fix! Limit to reasonable values - DeviceTimeFormat = "2006-01-02T15:04:05" - LegacyTimeFormat = "2006-01-02T15:04:05.000Z" - NoteLengthMaximum = 1000 - NotesLengthMaximum = 100 - TagLengthMaximum = 100 - TagsLengthMaximum = 100 - TimeFormat = time.RFC3339Nano - TimeZoneOffsetMaximum = 7 * 24 * 60 // TODO: Fix! Limit to reasonable values - TimeZoneOffsetMinimum = -7 * 24 * 60 // TODO: Fix! Limit to reasonable values - VersionInternalMinimum = 0 - - LegacyIdentityFieldsVersion = "0.0.0" - IdentityFieldsVersion = "1.1.0" + ClockDriftOffsetMaximum = 24 * 60 * 60 * 1000 // TODO: Fix! Limit to reasonable values + ClockDriftOffsetMinimum = -24 * 60 * 60 * 1000 // TODO: Fix! Limit to reasonable values + DeviceTimeFormat = "2006-01-02T15:04:05" + LegacyTimeFormat = "2006-01-02T15:04:05.000Z" + NoteLengthMaximum = 1000 + NotesLengthMaximum = 100 + TagLengthMaximum = 100 + TagsLengthMaximum = 100 + TimeFormat = time.RFC3339Nano + TimeZoneOffsetMaximum = 7 * 24 * 60 // TODO: Fix! Limit to reasonable values + TimeZoneOffsetMinimum = -7 * 24 * 60 // TODO: Fix! Limit to reasonable values + VersionInternalMinimum = 0 + LegacyIdentityFieldsVersion = 0 + IdentityFieldsVersion = 1 ) type Base struct { @@ -271,7 +270,7 @@ func currentIdentityFields(b *Base) ([]string, error) { return vals, nil } -func (b *Base) IdentityFields(version string) ([]string, error) { +func (b *Base) IdentityFields(version int) ([]string, error) { if version == LegacyIdentityFieldsVersion { return legacyIdentityFields(b) } diff --git a/data/types/base_test.go b/data/types/base_test.go index 90d9ba7138..1c2e837635 100644 --- a/data/types/base_test.go +++ b/data/types/base_test.go @@ -912,7 +912,7 @@ var _ = Describe("Base", func() { }) Context("with new, initialized datum", func() { - const currentVersion = "1.1.0" + const currentVersion = types.IdentityFieldsVersion var datumBase *types.Base var datum data.Datum diff --git a/data/types/blood/blood.go b/data/types/blood/blood.go index 813e45d87b..656160d2f6 100644 --- a/data/types/blood/blood.go +++ b/data/types/blood/blood.go @@ -30,7 +30,7 @@ func (b *Blood) Parse(parser structure.ObjectParser) { b.Value = parser.Float64("value") } -func (b *Blood) IdentityFields(version string) ([]string, error) { +func (b *Blood) IdentityFields(version int) ([]string, error) { if version == types.LegacyIdentityFieldsVersion { return b.Base.IdentityFields(version) } diff --git a/data/types/blood/blood_test.go b/data/types/blood/blood_test.go index 4547f0a6af..20aee08774 100644 --- a/data/types/blood/blood_test.go +++ b/data/types/blood/blood_test.go @@ -89,7 +89,7 @@ var _ = Describe("Blood", func() { }) Context("IdentityFields", func() { - const currentVersion = "1.1.0" + const currentVersion = types.IdentityFieldsVersion var datumBlood *blood.Blood var datum data.Datum diff --git a/data/types/blood/glucose/selfmonitored/selfmonitored.go b/data/types/blood/glucose/selfmonitored/selfmonitored.go index c101d8097d..0f8a0a5dca 100644 --- a/data/types/blood/glucose/selfmonitored/selfmonitored.go +++ b/data/types/blood/glucose/selfmonitored/selfmonitored.go @@ -70,7 +70,7 @@ func (s *SelfMonitored) Normalize(normalizer data.Normalizer) { s.Glucose.Normalize(normalizer) } -func (s *SelfMonitored) IdentityFields(version string) ([]string, error) { +func (s *SelfMonitored) IdentityFields(version int) ([]string, error) { if version == types.LegacyIdentityFieldsVersion { identityFields, err := s.Blood.IdentityFields(version) if err != nil { diff --git a/data/types/bolus/bolus.go b/data/types/bolus/bolus.go index 78ffb03248..1521f7187f 100644 --- a/data/types/bolus/bolus.go +++ b/data/types/bolus/bolus.go @@ -78,7 +78,7 @@ func (b *Bolus) Normalize(normalizer data.Normalizer) { } } -func (b *Bolus) IdentityFields(version string) ([]string, error) { +func (b *Bolus) IdentityFields(version int) ([]string, error) { identityFields := []string{} var err error diff --git a/data/types/calculator/calculator.go b/data/types/calculator/calculator.go index f469f0a98d..c414a457c4 100644 --- a/data/types/calculator/calculator.go +++ b/data/types/calculator/calculator.go @@ -118,7 +118,7 @@ func (c *Calculator) Validate(validator structure.Validator) { } } -func (c *Calculator) IdentityFields(version string) ([]string, error) { +func (c *Calculator) IdentityFields(version int) ([]string, error) { return c.Base.IdentityFields(version) } diff --git a/data/types/device/device.go b/data/types/device/device.go index 9b209c7e63..7dccb67e04 100644 --- a/data/types/device/device.go +++ b/data/types/device/device.go @@ -44,7 +44,7 @@ func (d *Device) Validate(validator structure.Validator) { validator.String("subType", &d.SubType).Exists().NotEmpty() } -func (d *Device) IdentityFields(version string) ([]string, error) { +func (d *Device) IdentityFields(version int) ([]string, error) { identityFields := []string{} var err error if version == types.LegacyIdentityFieldsVersion { diff --git a/data/types/device/device_test.go b/data/types/device/device_test.go index 7e122bbe6f..27a4f44da2 100644 --- a/data/types/device/device_test.go +++ b/data/types/device/device_test.go @@ -7,6 +7,7 @@ import ( . "github.com/onsi/gomega" "github.com/tidepool-org/platform/data" + "github.com/tidepool-org/platform/data/types" dataTypes "github.com/tidepool-org/platform/data/types" "github.com/tidepool-org/platform/data/types/device" dataTypesDeviceTest "github.com/tidepool-org/platform/data/types/device/test" @@ -94,7 +95,7 @@ var _ = Describe("Device", func() { }) Context("IdentityFields", func() { - const currentVersion = "1.1.0" + const currentVersion = types.IdentityFieldsVersion var datumDevice *device.Device var datum data.Datum diff --git a/data/types/food/food.go b/data/types/food/food.go index 84bcdd485d..1921b0f887 100644 --- a/data/types/food/food.go +++ b/data/types/food/food.go @@ -105,6 +105,6 @@ func (f *Food) Normalize(normalizer data.Normalizer) { f.Base.Normalize(normalizer) } -func (f *Food) IdentityFields(version string) ([]string, error) { +func (f *Food) IdentityFields(version int) ([]string, error) { return f.Base.IdentityFields(version) } diff --git a/data/types/insulin/insulin.go b/data/types/insulin/insulin.go index 13afaae8f9..e2029588f9 100644 --- a/data/types/insulin/insulin.go +++ b/data/types/insulin/insulin.go @@ -73,6 +73,6 @@ func (i *Insulin) Normalize(normalizer data.Normalizer) { } } -func (i *Insulin) IdentityFields(version string) ([]string, error) { +func (i *Insulin) IdentityFields(version int) ([]string, error) { return i.Base.IdentityFields(version) } diff --git a/data/types/settings/cgm/cgm.go b/data/types/settings/cgm/cgm.go index abd57a595e..248dabc40d 100644 --- a/data/types/settings/cgm/cgm.go +++ b/data/types/settings/cgm/cgm.go @@ -157,7 +157,7 @@ func (c *CGM) Normalize(normalizer data.Normalizer) { } } -func (c *CGM) IdentityFields(version string) ([]string, error) { +func (c *CGM) IdentityFields(version int) ([]string, error) { identityFields := []string{} var err error if version == types.LegacyIdentityFieldsVersion { From 49b293d648615414b4d65bafb954ff539453d8e0 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 6 Dec 2024 15:25:02 +1300 Subject: [PATCH 411/413] add SemanticVersion error --- data/deduplicator/deduplicator/base.go | 2 ++ data/deduplicator/deduplicator/base_test.go | 5 +---- data/deduplicator/deduplicator/device_deactivate_hash.go | 3 --- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/data/deduplicator/deduplicator/base.go b/data/deduplicator/deduplicator/base.go index daed7f31e3..19ad2ae6df 100644 --- a/data/deduplicator/deduplicator/base.go +++ b/data/deduplicator/deduplicator/base.go @@ -24,6 +24,8 @@ func NewBase(name string, version string) (*Base, error) { } if version == "" { return nil, errors.New("version is missing") + } else if !net.IsValidSemanticVersion(version) { + return nil, errors.New("version is invalid") } return &Base{ diff --git a/data/deduplicator/deduplicator/base_test.go b/data/deduplicator/deduplicator/base_test.go index e9da3eaa7f..94328ce37f 100644 --- a/data/deduplicator/deduplicator/base_test.go +++ b/data/deduplicator/deduplicator/base_test.go @@ -25,10 +25,7 @@ var _ = Describe("Base", func() { BeforeEach(func() { name = netTest.RandomReverseDomain() - version = test.RandomStringFromArray([]string{ - dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionCurrent, - dataDeduplicatorDeduplicator.DeviceDeactivateHashVersionLegacy, - }) + version = netTest.RandomSemanticVersion() }) Context("NewBase", func() { diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index 38bfec3b2e..9544ed677a 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -12,9 +12,6 @@ import ( ) const ( - - // LegacyIdentityFieldsVersion = "0.0.0" - // IdentityFieldsVersion = "1.1.0" DeviceDeactivateHashVersionLegacy = "0.0.0" DeviceDeactivateHashVersionCurrent = "1.1.0" ) From 2eefbf0cdc3f47d47785d9c9c00e63703405d2d0 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 11 Dec 2024 10:32:32 +1300 Subject: [PATCH 412/413] no longer required --- .../jellyfish_migration.go | 214 - .../20231128_jellyfish_migration/readme.md | 63 - .../utils/data_migration.go | 300 - .../utils/data_migration_test.go | 153 - .../utils/jellyfish_data.go | 175 - .../utils/mongo_instance_check.go | 226 - .../utils/output.go | 36 - .../utils/test/data.go | 211 - .../utils/utils_suite_test.go | 11 - .../verify/cleanup_user_data.sh | 28 - .../verify/data_verify.go | 451 - .../verify/data_verify_test.go | 161 - .../verify/fetch_blobs.sh | 81 - .../verify/process_all_blobs.sh | 32 - .../verify/test/data_verify.go | 81720 ---------------- .../verify/upload_blob.sh | 74 - .../verify/utils_suite_test.go | 11 - .../verify/verify.go | 227 - 18 files changed, 84174 deletions(-) delete mode 100644 migrations/20231128_jellyfish_migration/jellyfish_migration.go delete mode 100644 migrations/20231128_jellyfish_migration/readme.md delete mode 100644 migrations/20231128_jellyfish_migration/utils/data_migration.go delete mode 100644 migrations/20231128_jellyfish_migration/utils/data_migration_test.go delete mode 100644 migrations/20231128_jellyfish_migration/utils/jellyfish_data.go delete mode 100644 migrations/20231128_jellyfish_migration/utils/mongo_instance_check.go delete mode 100644 migrations/20231128_jellyfish_migration/utils/output.go delete mode 100644 migrations/20231128_jellyfish_migration/utils/test/data.go delete mode 100644 migrations/20231128_jellyfish_migration/utils/utils_suite_test.go delete mode 100644 migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh delete mode 100644 migrations/20231128_jellyfish_migration/verify/data_verify.go delete mode 100644 migrations/20231128_jellyfish_migration/verify/data_verify_test.go delete mode 100644 migrations/20231128_jellyfish_migration/verify/fetch_blobs.sh delete mode 100644 migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh delete mode 100644 migrations/20231128_jellyfish_migration/verify/test/data_verify.go delete mode 100644 migrations/20231128_jellyfish_migration/verify/upload_blob.sh delete mode 100644 migrations/20231128_jellyfish_migration/verify/utils_suite_test.go delete mode 100644 migrations/20231128_jellyfish_migration/verify/verify.go diff --git a/migrations/20231128_jellyfish_migration/jellyfish_migration.go b/migrations/20231128_jellyfish_migration/jellyfish_migration.go deleted file mode 100644 index a71610bc71..0000000000 --- a/migrations/20231128_jellyfish_migration/jellyfish_migration.go +++ /dev/null @@ -1,214 +0,0 @@ -package main - -import ( - "context" - "fmt" - "log" - "os" - "strings" - - "github.com/urfave/cli" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" - - "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" - "github.com/tidepool-org/platform/pointer" -) - -type Migration struct { - ctx context.Context - cli *cli.App - config *config - client *mongo.Client - migrationUtil *utils.DataMigration -} - -type config struct { - recordLimit int - mongoURI string - dryRun bool - stopOnErr bool - userID string - uploadID string - lastUpdatedID string - nopPercent int - queryBatchSize int - queryLimit int -} - -const DryRunFlag = "dry-run" -const StopOnErrorFlag = "stop-on-error" -const RecordLimitFlag = "record-limit" -const NopPercentFlag = "nop-percent" -const MongoURIFlag = "uri" -const DatumIDFlag = "datum-id" -const UserIDFlag = "user-id" -const UploadIDFlag = "upload-id" -const QueryLimitFlag = "query-limit" -const QueryBatchFlag = "query-batch" - -func main() { - ctx := context.Background() - ctx, cancel := context.WithCancel(ctx) - defer cancel() - migration := NewJellyfishMigration(ctx) - migration.RunAndExit() - log.Println("finished migration") -} - -func NewJellyfishMigration(ctx context.Context) *Migration { - return &Migration{ - config: &config{}, - ctx: ctx, - cli: cli.NewApp(), - } -} - -func (c *config) report() string { - details := "\nMIGRATION DETAILS:\n" - details += fmt.Sprintf("- %s\t\t\t[%d]\n", RecordLimitFlag, c.recordLimit) - details += fmt.Sprintf("- %s? \t\t[%t]\n", DryRunFlag, c.dryRun) - details += fmt.Sprintf("- %s\t\t[%t]\n", StopOnErrorFlag, c.stopOnErr) - details += fmt.Sprintf("- %s\t[%s]\n", DatumIDFlag, c.lastUpdatedID) - details += fmt.Sprintf("- %s\t\t[%s]\n", UserIDFlag, c.userID) - details += fmt.Sprintf("- %s\t\t[%d]\n", QueryBatchFlag, c.queryBatchSize) - details += fmt.Sprintf("- %s\t\t[%d]\n", QueryLimitFlag, c.queryLimit) - details += fmt.Sprintf("- %s\t\t[%s]\n", UploadIDFlag, c.uploadID) - return details -} - -func (m *Migration) RunAndExit() { - if err := m.Initialize(); err != nil { - os.Exit(1) - } - - m.CLI().Action = func(ctx *cli.Context) error { - - var err error - m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(strings.TrimSpace(m.config.mongoURI))) - if err != nil { - return fmt.Errorf("unable to connect to MongoDB: %w", err) - } - defer m.client.Disconnect(m.ctx) - - dbChecker := utils.NewMongoInstanceCheck( - m.client, - utils.NewMongoInstanceCheckConfig(&m.config.nopPercent), - ) - - m.migrationUtil, err = utils.NewMigration( - m.ctx, - utils.NewSettings( - &m.config.dryRun, - &m.config.stopOnErr, - &m.config.recordLimit, - &m.config.queryBatchSize, - &m.config.queryLimit, - pointer.FromBool(true), - ), - dbChecker, - m.client.Database("data").Collection("deviceData"), - &m.config.lastUpdatedID, - ) - - log.Println(m.config.report()) - - if err != nil { - return fmt.Errorf("unable to create migration utils : %w", err) - } - - if err := m.migrationUtil.Initialize(); err != nil { - log.Printf("prepare failed: %s", err) - return err - } - if err := m.migrationUtil.Execute(utils.JellyfishDataQueryFn, utils.JellyfishDataUpdatesFn); err != nil { - log.Printf("execute failed: %s", err) - return err - } - return nil - } - - if err := m.CLI().Run(os.Args); err != nil { - if m.client != nil { - m.client.Disconnect(m.ctx) - } - os.Exit(1) - } -} - -func (m *Migration) Initialize() error { - m.CLI().Usage = "BACK-37: Migrate all existing data to add required Platform deduplication hash fields" - m.CLI().Description = "BACK-37: To fully migrate devices from the `jellyfish` upload API to the `platform` upload API" - m.CLI().Authors = []cli.Author{ - { - Name: "J H BATE", - Email: "jamie@tidepool.org", - }, - } - m.CLI().Flags = append(m.CLI().Flags, - cli.BoolFlag{ - Name: fmt.Sprintf("%s,%s", DryRunFlag, "n"), - Usage: "dry run only; do not migrate", - Destination: &m.config.dryRun, - }, - cli.BoolFlag{ - Name: StopOnErrorFlag, - Usage: "stop migration on error", - Destination: &m.config.stopOnErr, - }, - cli.IntFlag{ - Name: RecordLimitFlag, - Usage: "max number of records migrate", - Destination: &m.config.recordLimit, - Required: false, - }, - cli.IntFlag{ - Name: NopPercentFlag, - Usage: "how much of the oplog is NOP", - Destination: &m.config.nopPercent, - Value: 50, - Required: false, - }, - cli.StringFlag{ - Name: MongoURIFlag, - Usage: "mongo connection URI", - Destination: &m.config.mongoURI, - Required: false, - //uri string comes from file called `uri` - FilePath: "./uri", - }, - cli.StringFlag{ - Name: DatumIDFlag, - Usage: "id of last datum updated", - Destination: &m.config.lastUpdatedID, - Required: false, - //id of last datum updated read and written to file `lastProcessedId` - FilePath: "./lastProcessedId", - }, - cli.StringFlag{ - Name: UserIDFlag, - Usage: "id of single user to migrate", - Destination: &m.config.userID, - Required: false, - }, - cli.IntFlag{ - Name: QueryLimitFlag, - Usage: "max number of items to return", - Destination: &m.config.queryLimit, - Value: 50000, - Required: false, - }, - cli.IntFlag{ - Name: QueryBatchFlag, - Usage: "max number of items in each query batch", - Destination: &m.config.queryBatchSize, - Value: 10000, - Required: false, - }, - ) - return nil -} - -func (m *Migration) CLI() *cli.App { - return m.cli -} diff --git a/migrations/20231128_jellyfish_migration/readme.md b/migrations/20231128_jellyfish_migration/readme.md deleted file mode 100644 index a4dc508ce9..0000000000 --- a/migrations/20231128_jellyfish_migration/readme.md +++ /dev/null @@ -1,63 +0,0 @@ -# Running jellyfish migration tool - -## login to server with mongo access - -## clone platform repo - -## set `uri` for migration too -- go to `platform/cd migrations/20231128_jellyfish_migration/` -- create file `uri` -- add single line to file with mongo connection string `mongodb+srv:///?retryWrites=true&w=majority` - -## run tool -- help: -``` -GLOBAL OPTIONS: - --dry-run, -n dry run only; do not migrate - --stop-on-error stop migration on error - --audit run audit - --cap value max number of records migrate (default: 0) - --nop-percent value how much of the oplog is NOP (default: 50) - --uri value mongo connection URI [./uri] - --datum-id value id of last datum updated [./lastUpdatedId] - --user-id value id of single user to migrate - --query-limit value max number of items to return (default: 50000) - --query-batch value max number of items in each query batch (default: 10000) - --help, -h show help - -``` -- test migration for a user: - `go run jellyfish_migration.go --user-id=924edd2e-b8fc-45ad-b3f4-3032bb6b0a45 --stop-error --dry-run` - -- run migration: - `go run jellyfish_migration.go --user-id=924edd2e-b8fc-45ad-b3f4-3032bb6b0a45` - - -- finding upload records with blobs - -``` -[ - { "$match": { "deviceManufacturers": { "$in": ["Tandem", "Insulet"] }, "client.private.blobId": { "$exists": true }}}, - { "$project": { "blobId": "$client.private.blobId", "_userId": 1, "deviceId": 1}}, - { "$group": { "_id": "$_userId", "detail": { "$push": "$$ROOT" }}} -] -``` - -- finding error types - -grep -c "InsOmn.*Checksum" prod_blob_error.log -grep -c "InsOmn.*rawdata" prod_blob_error.log -grep -c "InsOmn.*value-not-exists" prod_blob_error.log -grep -c "InsOmn.*value-out-of-range" prod_blob_error.log - -grep -c "tandem" prod_blob_error.log - - -cat prod_blob_upload.log | grep "InsOmn" | sed -n 's/.*records: \([0-9]*\).*/\1/p' | awk '{sum+=$1} END {print sum}' -cat prod_blob_upload.log | grep "InsOmn" | sed -n 's/.*upload \([0-9]*\).*/\1/p' | awk '{sum+=$1} END {print sum}' - -cat prod_blob_upload.log | grep "tandem" | sed -n 's/.*records: \([0-9]*\).*/\1/p' | awk '{sum+=$1} END {print sum}' -cat prod_blob_upload.log | grep "tandem" | sed -n 's/.*upload \([0-9]*\).*/\1/p' | awk '{sum+=$1} END {print sum}' - - - diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration.go b/migrations/20231128_jellyfish_migration/utils/data_migration.go deleted file mode 100644 index 102b2255df..0000000000 --- a/migrations/20231128_jellyfish_migration/utils/data_migration.go +++ /dev/null @@ -1,300 +0,0 @@ -package utils - -import ( - "context" - "errors" - "fmt" - "log" - "os" - "path/filepath" - "strings" - "time" - - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" -) - -type UpdateData struct { - Filter interface{} `json:"-"` - ItemID string `json:"_id"` - Apply []bson.M `json:"apply"` -} - -type ErrorData struct { - Error error `json:"error"` - ItemID string `json:"_id"` - ItemType string `json:"-"` - Msg string `json:"message,omitempty"` -} - -type MigrationStats struct { - Errored int - Fetched int - Applied int - ToApply int - Elapsed time.Duration -} - -type Settings struct { - DryRun bool - StopOnErr bool - WriteBatchSize *int64 - QueryBatchSize int - QueryBatchLimit int - - RecordLimit *int - writeToDisk bool -} - -func NewSettings(dryRun *bool, stopOnErr *bool, recordLimit *int, queryBatchSize *int, queryBatchLimit *int, writeToDisk *bool) *Settings { - settings := &Settings{ - writeToDisk: false, - DryRun: true, - StopOnErr: true, - QueryBatchSize: 50, - QueryBatchLimit: 100, - } - if dryRun != nil { - settings.DryRun = *dryRun - } - if stopOnErr != nil { - settings.StopOnErr = *stopOnErr - } - - if writeToDisk != nil { - settings.writeToDisk = *writeToDisk - } - if queryBatchSize != nil { - settings.QueryBatchSize = *queryBatchSize - } - if queryBatchLimit != nil { - settings.QueryBatchLimit = *queryBatchLimit - } - if recordLimit != nil && *recordLimit > 0 { - settings.RecordLimit = recordLimit - log.Printf("capped at %d items", *settings.RecordLimit) - } - return settings -} - -type DataMigration struct { - ctx context.Context - dataC *mongo.Collection - settings *Settings - updates []mongo.WriteModel - groupedDiffs map[string][]UpdateData - groupedErrors groupedErrors - errorsCount int - updatedCount int - fetchedCount int - lastUpdatedID *string - startedAt time.Time - mongoInstanceChecker MongoInstanceCheck -} - -type DataMigrationQueryFn func(m *DataMigration) bool -type DataMigrationUpdateFn func(m *DataMigration) (int, error) - -type groupedErrors map[string][]ErrorData - -func NewMigration(ctx context.Context, settings *Settings, checker MongoInstanceCheck, dataC *mongo.Collection, lastID *string) (*DataMigration, error) { - var err error - if settings == nil { - err = errors.Join(err, errors.New("missing required settings")) - } - if checker == nil { - err = errors.Join(err, errors.New("missing required mongo checker")) - } - - if err != nil { - return nil, err - } - - m := &DataMigration{ - ctx: ctx, - dataC: dataC, - mongoInstanceChecker: checker, - settings: settings, - updates: []mongo.WriteModel{}, - groupedErrors: groupedErrors{}, - groupedDiffs: map[string][]UpdateData{}, - errorsCount: 0, - updatedCount: 0, - fetchedCount: 0, - startedAt: time.Now(), - lastUpdatedID: lastID, - } - - return m, nil -} - -func (m *DataMigration) Initialize() error { - if err := m.mongoInstanceChecker.CheckFreeSpace(m.ctx, m.dataC); err != nil { - return err - } - if err := m.mongoInstanceChecker.SetWriteBatchSize(m.ctx); err != nil { - return err - } - return nil -} - -func (m *DataMigration) GetCtx() context.Context { - return m.ctx -} - -func (m *DataMigration) GetSettings() Settings { - m.settings.WriteBatchSize = m.mongoInstanceChecker.GetWriteBatchSize() - return *m.settings -} - -func (m *DataMigration) GetDataCollection() *mongo.Collection { - return m.dataC -} - -func (m *DataMigration) Execute( - queryFn DataMigrationQueryFn, - updateFn DataMigrationUpdateFn) error { - for queryFn(m) { - count, err := updateFn(m) - if err != nil { - m.writeErrors() - return err - } - m.updatesApplied(count) - if m.completeUpdates() { - break - } - m.writeErrors() - m.writeAudit() - } - m.GetStats().report() - m.writeErrors() - m.writeAudit() - return nil -} - -func (d UpdateData) getMongoUpdates() []mongo.WriteModel { - updates := []mongo.WriteModel{} - for _, u := range d.Apply { - updateOp := mongo.NewUpdateOneModel() - updateOp.Filter = d.Filter - updateOp.SetUpdate(u) - updates = append(updates, updateOp) - } - return updates -} - -func (m *DataMigration) SetUpdates(data UpdateData) { - m.updates = append(m.updates, data.getMongoUpdates()...) -} - -func (m *DataMigration) updatesApplied(updatedCount int) { - m.updates = []mongo.WriteModel{} - m.updatedCount += updatedCount -} - -func (m *DataMigration) completeUpdates() bool { - recordLimit := m.settings.RecordLimit - stats := m.GetStats() - if recordLimit == nil { - log.Printf("updates applied [%d] fetched [%d]", stats.Applied, stats.Fetched) - } else { - percent := (float64(stats.Fetched) * float64(100)) / float64(*recordLimit) - log.Printf("processed %.0f %% of %d records and applied %d changes", percent, *recordLimit, stats.Applied) - - if *recordLimit <= stats.Applied || *recordLimit <= stats.Fetched { - log.Printf("recordLimit [%d] updates applied [%d] fetched [%d]", *recordLimit, stats.Applied, stats.Fetched) - return true - } - } - return false -} - -func (m *DataMigration) GetUpdates() []mongo.WriteModel { - return m.updates -} - -func (m *DataMigration) SetLastProcessed(lastID string) { - m.lastUpdatedID = &lastID - m.writeLastProcessed(*m.lastUpdatedID) -} - -func (m *DataMigration) UpdateFetchedCount() { - m.fetchedCount++ -} - -func (m *DataMigration) GetStats() MigrationStats { - return MigrationStats{ - Errored: m.errorsCount, - Fetched: m.fetchedCount, - ToApply: len(m.updates), - Applied: m.updatedCount, - Elapsed: time.Since(m.startedAt).Truncate(time.Millisecond), - } -} - -func (m *DataMigration) GetLastID() *string { - return m.lastUpdatedID -} - -func (m *DataMigration) OnError(data ErrorData) { - if m.settings.StopOnErr { - log.Printf("[_id=%s] %s %s\n", data.ItemID, data.Msg, data.Error.Error()) - os.Exit(1) - } - m.errorsCount++ - m.groupedErrors[data.ItemType] = append(m.groupedErrors[data.ItemType], data) -} - -func (m *DataMigration) CheckMongoInstance() error { - if err := m.mongoInstanceChecker.BlockUntilDBReady(m.GetCtx()); err != nil { - return err - } - if err := m.mongoInstanceChecker.CheckFreeSpace(m.GetCtx(), m.GetDataCollection()); err != nil { - return err - } - return nil -} - -func (c MigrationStats) report() { - if c.Applied == 0 && c.Fetched > 0 { - log.Printf("elapsed [%s] for [%d] items fetched with [%d] errors\n", c.Elapsed, c.Fetched, c.Errored) - return - } - log.Printf("elapsed [%s] for [%d] fetched [%d] updates applied with [%d] errors\n", c.Elapsed, c.Fetched, c.Applied, c.Errored) -} - -func (m *DataMigration) writeErrors() { - if !m.settings.writeToDisk { - m.groupedErrors = map[string][]ErrorData{} - } - for group, errors := range m.groupedErrors { - writeFileData(errors, filepath.Join(".", "error"), fmt.Sprintf("%s.log", group), false) - m.groupedErrors[group] = []ErrorData{} - } -} - -func (m *DataMigration) writeAudit() { - if !m.settings.writeToDisk || !m.settings.DryRun { - m.groupedDiffs = map[string][]UpdateData{} - return - } - for group, diffs := range m.groupedDiffs { - writeFileData(diffs, filepath.Join(".", "audit"), fmt.Sprintf("%s.json", group), true) - m.groupedDiffs[group] = []UpdateData{} - } -} - -func (m *DataMigration) writeLastProcessed(itemID string) { - if m.settings.writeToDisk { - if strings.TrimSpace(itemID) != "" { - f, err := os.Create("./lastProcessedId") - if err != nil { - log.Println(err) - os.Exit(1) - } - defer f.Close() - f.WriteString(itemID) - } - } -} diff --git a/migrations/20231128_jellyfish_migration/utils/data_migration_test.go b/migrations/20231128_jellyfish_migration/utils/data_migration_test.go deleted file mode 100644 index 860c3ee0c4..0000000000 --- a/migrations/20231128_jellyfish_migration/utils/data_migration_test.go +++ /dev/null @@ -1,153 +0,0 @@ -package utils_test - -import ( - "context" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" - - "github.com/tidepool-org/platform/data/deduplicator/deduplicator" - dataStoreMongo "github.com/tidepool-org/platform/data/store/mongo" - platformLog "github.com/tidepool-org/platform/log" - logTest "github.com/tidepool-org/platform/log/test" - "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils" - "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/utils/test" - "github.com/tidepool-org/platform/pointer" - storeStructuredMongoTest "github.com/tidepool-org/platform/store/structured/mongo/test" -) - -type mongoInstance struct { - writeBatchSize *int64 -} - -func newMongoInstanceChecker() utils.MongoInstanceCheck { - return &mongoInstance{ - writeBatchSize: pointer.FromInt64(100), - } -} - -func (m *mongoInstance) SetWriteBatchSize(ctx context.Context) error { - return nil -} -func (m *mongoInstance) CheckFreeSpace(ctx context.Context, dataC *mongo.Collection) error { - return nil -} -func (m *mongoInstance) BlockUntilDBReady(ctx context.Context) error { - return nil -} -func (m *mongoInstance) GetWriteBatchSize() *int64 { - return m.writeBatchSize -} - -func setCollectionData(ctx context.Context, dataC *mongo.Collection, dataSetData []map[string]interface{}) error { - insertData := make([]mongo.WriteModel, 0, len(dataSetData)) - for _, datum := range dataSetData { - insertData = append(insertData, mongo.NewInsertOneModel().SetDocument(datum)) - } - opts := options.BulkWrite().SetOrdered(false) - _, err := dataC.BulkWrite(ctx, insertData, opts) - return err -} - -var _ = Describe("back-37", func() { - var _ = Describe("migrationUtil", func() { - - var testJFData []map[string]interface{} - var testJFUploads []map[string]interface{} - const datumCount = 1000 - const uploadCount = 99 - var store *dataStoreMongo.Store - var ctx context.Context - var migrationSettings *utils.Settings - - BeforeEach(func() { - logger := logTest.NewLogger() - ctx = platformLog.NewContextWithLogger(context.Background(), logger) - testJFData = test.BulkJellyfishData("test-device-88x89", "test-group-id", "test-user-id-123", datumCount) - testJFUploads = test.BulkJellyfishData("test-device-other", "test-group-id_2", "test-user-id-987", uploadCount) - - migrationSettings = utils.NewSettings( - pointer.FromBool(false), - pointer.FromBool(false), - nil, - pointer.FromInt(50), - pointer.FromInt(100), - pointer.FromBool(false), - ) - var err error - store, err = dataStoreMongo.NewStore(storeStructuredMongoTest.NewConfig()) - Expect(err).ToNot(HaveOccurred()) - Expect(store).ToNot(BeNil()) - }) - AfterEach(func() { - if store != nil { - _ = store.Terminate(ctx) - } - }) - It("will set _deduplicator.hash to be the datum _id for jellyfish data", func() { - collection := store.GetCollection("testJFDatum") - Expect(setCollectionData(ctx, collection, testJFData)).To(Succeed()) - - migration, err := utils.NewMigration(ctx, migrationSettings, newMongoInstanceChecker(), collection, nil) - Expect(err).To(BeNil()) - - Expect(testJFData).ToNot(BeNil()) - Expect(len(testJFData)).To(Equal(datumCount)) - allDocs, err := collection.CountDocuments(ctx, bson.D{}) - Expect(err).To(BeNil()) - Expect(allDocs).To(Equal(int64(datumCount))) - Expect(migration.Execute(utils.JellyfishDataQueryFn, utils.JellyfishDataUpdatesFn)).To(Succeed()) - stats := migration.GetStats() - Expect(stats.Errored).To(Equal(0)) - Expect(stats.Fetched).To(Equal(datumCount)) - Expect(stats.Applied).To(Equal(datumCount)) - cur, err := collection.Find(ctx, bson.D{}) - Expect(err).To(BeNil()) - migrated := []map[string]interface{}{} - cur.All(ctx, &migrated) - - Expect(len(migrated)).To(Equal(datumCount)) - - for _, item := range migrated { - Expect(item).Should(HaveKey("_deduplicator")) - Expect(item["_deduplicator"]).Should(HaveLen(1)) - Expect(item["_deduplicator"]).Should(HaveKeyWithValue("hash", item["_id"])) - } - }) - - It("will set _deduplicator to be the datum _id for jellyfish uploads", func() { - collection := store.GetCollection("testJFUploads") - Expect(setCollectionData(ctx, collection, testJFUploads)).To(Succeed()) - - migration, err := utils.NewMigration(ctx, migrationSettings, newMongoInstanceChecker(), collection, nil) - Expect(err).To(BeNil()) - - Expect(testJFUploads).ToNot(BeNil()) - Expect(len(testJFUploads)).To(Equal(uploadCount)) - allUploadDocs, err := collection.CountDocuments(ctx, bson.D{}) - Expect(err).To(BeNil()) - Expect(allUploadDocs).To(Equal(int64(uploadCount))) - Expect(migration.Execute(utils.JellyfishUploadQueryFn, utils.JellyfishDataUpdatesFn)).To(Succeed()) - stats := migration.GetStats() - Expect(stats.Errored).To(Equal(0)) - Expect(stats.Fetched).To(Equal(uploadCount)) - Expect(stats.Applied).To(Equal(uploadCount)) - cur, err := collection.Find(ctx, bson.D{}) - Expect(err).To(BeNil()) - migrated := []map[string]interface{}{} - cur.All(ctx, &migrated) - - Expect(len(migrated)).To(Equal(uploadCount)) - - for _, item := range migrated { - Expect(item).Should(HaveKey("_deduplicator")) - Expect(item["_deduplicator"]).Should(HaveLen(2)) - Expect(item["_deduplicator"]).Should(HaveKeyWithValue("name", deduplicator.DeviceDeactivateHashName)) - Expect(item["_deduplicator"]).Should(HaveKeyWithValue("version", "0.0.0")) - } - }) - }) -}) diff --git a/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go b/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go deleted file mode 100644 index bb1cc437b7..0000000000 --- a/migrations/20231128_jellyfish_migration/utils/jellyfish_data.go +++ /dev/null @@ -1,175 +0,0 @@ -package utils - -import ( - "errors" - "log" - - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" - - "github.com/tidepool-org/platform/data/deduplicator/deduplicator" -) - -func jellyfishQuery(settings Settings, userID *string, lastFetchedID *string) (bson.M, *options.FindOptions) { - selector := bson.M{ - "_deduplicator": bson.M{"$exists": false}, - } - - if userID != nil && *userID != "" { - log.Printf("fetching for user %s", *userID) - selector["_userId"] = *userID - } - idNotObjectID := bson.M{"$not": bson.M{"$type": "objectId"}} - - if lastFetchedID != nil && *lastFetchedID != "" { - selector["$and"] = []interface{}{ - bson.M{"_id": bson.M{"$gt": *lastFetchedID}}, - bson.M{"_id": idNotObjectID}, - } - } else { - selector["_id"] = idNotObjectID - } - - bSize := int32(settings.QueryBatchSize) - limit := int64(settings.QueryBatchLimit) - opts := &options.FindOptions{ - Sort: bson.M{"_id": 1}, - BatchSize: &bSize, - Limit: &limit, - } - - return selector, opts -} - -var JellyfishDataQueryFn = func(m *DataMigration) bool { - - settings := m.GetSettings() - - if dataC := m.GetDataCollection(); dataC != nil { - - selector, opts := jellyfishQuery( - settings, - nil, - m.GetLastID(), - ) - - opts.Projection = bson.M{"_id": 1} - dDataCursor, err := dataC.Find(m.GetCtx(), selector, opts) - if err != nil { - log.Printf("failed to select data: %s", err) - return false - } - defer dDataCursor.Close(m.GetCtx()) - - count := 0 - - for dDataCursor.Next(m.GetCtx()) { - m.UpdateFetchedCount() - var result struct { - ID string `bson:"_id"` - } - if err := dDataCursor.Decode(&result); err != nil { - m.OnError(ErrorData{Error: err}) - continue - } else { - setDeduplicator := bson.M{"$set": bson.M{"_deduplicator": bson.M{"hash": result.ID}}} - m.SetUpdates(UpdateData{ - Filter: bson.M{"_id": result.ID}, - ItemID: result.ID, - Apply: []bson.M{setDeduplicator}, - }) - count++ - m.SetLastProcessed(result.ID) - } - } - return count > 0 - } - return false -} - -var JellyfishDataUpdatesFn = func(m *DataMigration) (int, error) { - settings := m.GetSettings() - updates := m.GetUpdates() - dataC := m.GetDataCollection() - if dataC == nil { - return 0, errors.New("missing required collection to write updates to") - } - if len(updates) == 0 { - return 0, nil - } - - var getBatches = func(chunkSize int) [][]mongo.WriteModel { - batches := [][]mongo.WriteModel{} - for i := 0; i < len(updates); i += chunkSize { - end := i + chunkSize - if end > len(updates) { - end = len(updates) - } - batches = append(batches, updates[i:end]) - } - return batches - } - writtenCount := 0 - for _, batch := range getBatches(int(*settings.WriteBatchSize)) { - if err := m.CheckMongoInstance(); err != nil { - return writtenCount, err - } - if settings.DryRun { - writtenCount += len(batch) - continue - } - results, err := dataC.BulkWrite(m.GetCtx(), batch) - if err != nil { - log.Printf("error writing batch updates %v", err) - return writtenCount, err - } - writtenCount += int(results.ModifiedCount) - } - return writtenCount, nil -} - -var JellyfishUploadQueryFn = func(m *DataMigration) bool { - - settings := m.GetSettings() - - if dataC := m.GetDataCollection(); dataC != nil { - - selector, opts := jellyfishQuery( - settings, - nil, - m.GetLastID(), - ) - - opts.Projection = bson.M{"_id": 1} - dDataCursor, err := dataC.Find(m.GetCtx(), selector, opts) - if err != nil { - log.Printf("failed to select upload data: %s", err) - return false - } - defer dDataCursor.Close(m.GetCtx()) - - count := 0 - - for dDataCursor.Next(m.GetCtx()) { - m.UpdateFetchedCount() - var result struct { - ID string `bson:"_id"` - } - if err := dDataCursor.Decode(&result); err != nil { - m.OnError(ErrorData{Error: err}) - continue - } else { - m.SetUpdates(UpdateData{ - Filter: bson.M{"_id": result.ID}, - ItemID: result.ID, - Apply: []bson.M{{"$set": bson.M{"_deduplicator": bson.M{"name": deduplicator.DeviceDeactivateHashName, "version": "0.0.0"}}}}, - }) - count++ - m.SetLastProcessed(result.ID) - } - } - return count > 0 - } - return false -} diff --git a/migrations/20231128_jellyfish_migration/utils/mongo_instance_check.go b/migrations/20231128_jellyfish_migration/utils/mongo_instance_check.go deleted file mode 100644 index 332411137a..0000000000 --- a/migrations/20231128_jellyfish_migration/utils/mongo_instance_check.go +++ /dev/null @@ -1,226 +0,0 @@ -package utils - -import ( - "context" - "errors" - "fmt" - "log" - "math" - "time" - - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" -) - -type MongoInstanceCheckConfig struct { - minOplogWindow int - // these values are used to determine writes batches, first dividing the oplog's size with the desired duration and - // expected entry size, then adding a divisor to account for NOP overshoot in the oplog - expectedOplogEntrySize int - // how much of the oplog is NOP, this adjusts the batch to account for an oplog that is very change sensitive - // must be > 0 - // prod 0.6 - // idle 100 - nopPercent int - // minimum free disk space percent - minFreePercent int -} - -func NewMongoInstanceCheckConfig(nopPercent *int) *MongoInstanceCheckConfig { - cfg := &MongoInstanceCheckConfig{ - minOplogWindow: 28800, // 8hrs - minFreePercent: 10, - expectedOplogEntrySize: 420, - nopPercent: 25, - } - if nopPercent != nil { - cfg.SetNopPercent(*nopPercent) - } - return cfg -} - -func (c *MongoInstanceCheckConfig) SetNopPercent(nopPercent int) *MongoInstanceCheckConfig { - c.nopPercent = nopPercent - return c -} -func (c *MongoInstanceCheckConfig) SetMinOplogWindow(minOplogWindow int) *MongoInstanceCheckConfig { - c.minOplogWindow = minOplogWindow - return c -} -func (c *MongoInstanceCheckConfig) SetExpectedOplogEntrySize(expectedOplogEntrySize int) *MongoInstanceCheckConfig { - c.expectedOplogEntrySize = expectedOplogEntrySize - return c -} -func (c *MongoInstanceCheckConfig) SetMinFreePercent(minFreePercent int) *MongoInstanceCheckConfig { - c.minFreePercent = minFreePercent - return c -} - -type MongoInstanceCheck interface { - BlockUntilDBReady(ctx context.Context) error - CheckFreeSpace(ctx context.Context, dataC *mongo.Collection) error - GetWriteBatchSize() *int64 - SetWriteBatchSize(ctx context.Context) error -} - -type mongoInstance struct { - client *mongo.Client - config *MongoInstanceCheckConfig - writeBatchSize *int64 -} - -func NewMongoInstanceCheck(client *mongo.Client, config *MongoInstanceCheckConfig) MongoInstanceCheck { - return &mongoInstance{ - client: client, - config: config, - } -} - -func (m *mongoInstance) GetWriteBatchSize() *int64 { - return m.writeBatchSize -} - -func (m *mongoInstance) SetWriteBatchSize(ctx context.Context) error { - var calculateBatchSize = func(oplogSize int, oplogEntryBytes int, oplogMinWindow int, nopPercent int) int64 { - return int64(math.Floor(float64(oplogSize) / float64(oplogEntryBytes) / float64(oplogMinWindow) / (float64(nopPercent) / 7))) - } - - if oplogC := m.getOplogCollection(); oplogC != nil { - type MongoMetaData struct { - MaxSize int `json:"maxSize"` - } - var metaData MongoMetaData - if err := oplogC.Database().RunCommand(ctx, bson.M{"collStats": "oplog.rs"}).Decode(&metaData); err != nil { - return err - } - writeBatchSize := calculateBatchSize(metaData.MaxSize, m.config.expectedOplogEntrySize, m.config.minOplogWindow, m.config.nopPercent) - m.writeBatchSize = &writeBatchSize - log.Printf("calculated writeBatchSize: %d", writeBatchSize) - return nil - } - var writeBatchSize = int64(30000) - log.Printf("MongoDB is not clustered, removing write batch limit, setting to %d documents.", writeBatchSize) - m.writeBatchSize = &writeBatchSize - return nil -} - -func (m *mongoInstance) CheckFreeSpace(ctx context.Context, dataC *mongo.Collection) error { - if dataC == nil { - return errors.New("missing required mongo data collection") - } - - type MongoMetaData struct { - FsTotalSize int `json:"fsTotalSize"` - FsUsedSize int `json:"fsUsedSize"` - } - var metaData MongoMetaData - - if err := dataC.Database().RunCommand(ctx, bson.M{"dbStats": 1}).Decode(&metaData); err != nil { - return err - } - bytesFree := metaData.FsTotalSize - metaData.FsUsedSize - percentFree := int(math.Floor(float64(bytesFree) / float64(metaData.FsTotalSize) * 100)) - if m.config.minFreePercent > percentFree { - return fmt.Errorf("error %d%% is below minimum free space of %d%%", percentFree, m.config.minFreePercent) - } - return nil -} - -func (m *mongoInstance) BlockUntilDBReady(ctx context.Context) error { - waitTime, err := m.getWaitTime(ctx) - if err != nil { - return err - } - var totalWait float64 - for waitTime > 0 { - totalWait += waitTime - if totalWait > 1800 { - log.Printf("Long total wait of %s, possibly high load, or sustained DB outage. If neither, adjust NOP_PERCENT to reduce overshoot.", time.Duration(totalWait)*time.Second) - } - log.Printf("Sleeping for %d", time.Duration(waitTime)*time.Second) - time.Sleep(time.Duration(waitTime) * time.Second) - waitTime, err = m.getWaitTime(ctx) - if err != nil { - log.Printf("failed getting wait time %d", time.Duration(waitTime)*time.Second) - return err - } - } - return nil -} -func (m *mongoInstance) getWaitTime(ctx context.Context) (float64, error) { - type Member struct { - Name string `json:"name"` - Health int `json:"health"` - Uptime int `json:"uptime"` - State int `json:"state"` - } - - type MongoMetaData struct { - Members []Member `json:"members"` - } - - var metaData MongoMetaData - if err := m.getAdminDB().RunCommand(ctx, bson.M{"replSetGetStatus": 1}).Decode(&metaData); err != nil { - return 0, err - } - - for _, member := range metaData.Members { - if member.State < 1 || member.State > 2 || member.Health != 1 || member.Uptime < 120 { - log.Printf("DB member %s down or not ready.", member.Name) - return 240, nil - } - } - - oplogDuration, err := m.getOplogDuration(ctx) - if err != nil { - return 0, err - } - if oplogDuration.Seconds() < float64(m.config.minOplogWindow) { - minOplogWindowTime := time.Duration(m.config.minOplogWindow) * time.Second - log.Printf("DB oplog shorter than requested duration of %s, currently %s.", minOplogWindowTime, oplogDuration) - waitTime := float64(m.config.minOplogWindow) - oplogDuration.Seconds() - waitTime *= 1.15 - if waitTime < 600 { - waitTime = 600 - } - return waitTime, nil - } - return 0, nil -} - -func (m *mongoInstance) getOplogCollection() *mongo.Collection { - return m.client.Database("local").Collection("oplog.rs") -} - -func (m *mongoInstance) getAdminDB() *mongo.Database { - return m.client.Database("admin") -} - -func (m *mongoInstance) getOplogDuration(ctx context.Context) (time.Duration, error) { - type MongoMetaData struct { - Wall time.Time `json:"wall"` - } - if oplogC := m.getOplogCollection(); oplogC != nil { - var oldest MongoMetaData - if err := oplogC.FindOne( - ctx, - bson.M{"wall": bson.M{"$exists": true}}, - options.FindOne().SetSort(bson.M{"$natural": 1})).Decode(&oldest); err != nil { - return 0, err - } - - var newest MongoMetaData - if err := oplogC.FindOne( - ctx, - bson.M{"wall": bson.M{"$exists": true}}, - options.FindOne().SetSort(bson.M{"$natural": -1})).Decode(&newest); err != nil { - return 0, err - } - oplogDuration := newest.Wall.Sub(oldest.Wall) - return oplogDuration, nil - } - log.Println("Not clustered, not retrieving oplog duration.") - oplogDuration := time.Duration(m.config.minOplogWindow+1) * time.Second - return oplogDuration, nil -} diff --git a/migrations/20231128_jellyfish_migration/utils/output.go b/migrations/20231128_jellyfish_migration/utils/output.go deleted file mode 100644 index 7182bd8285..0000000000 --- a/migrations/20231128_jellyfish_migration/utils/output.go +++ /dev/null @@ -1,36 +0,0 @@ -package utils - -import ( - "encoding/json" - "fmt" - "log" - "os" -) - -func writeFileData(data interface{}, path string, name string, asJSON bool) { - if data == nil || path == "" || name == "" { - return - } - - var handleErr = func(err error) { - if err != nil { - log.Println(err) - os.Exit(1) - } - } - - err := os.MkdirAll(path, os.ModePerm) - handleErr(err) - f, err := os.OpenFile(fmt.Sprintf("%s/%s", path, name), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - handleErr(err) - - defer f.Close() - - if asJSON { - jsonData, err := json.Marshal(data) - handleErr(err) - f.WriteString(string(jsonData) + "\n") - return - } - f.WriteString(fmt.Sprintf("%v", data)) -} diff --git a/migrations/20231128_jellyfish_migration/utils/test/data.go b/migrations/20231128_jellyfish_migration/utils/test/data.go deleted file mode 100644 index b2cddfe2bc..0000000000 --- a/migrations/20231128_jellyfish_migration/utils/test/data.go +++ /dev/null @@ -1,211 +0,0 @@ -package test - -import ( - "crypto/sha1" - "encoding/base32" - "io" - "strings" - "time" - - "github.com/tidepool-org/platform/test" -) - -func datumBase(deviceID string, groupID string, userID string, t time.Time) map[string]interface{} { - now := time.Now() - return map[string]interface{}{ - "_id": "17dbokav5t6pssjv72gm0nie3u25b54m", - "deviceId": deviceID, - "deviceTime": t.Format("2006-01-02T15:04:05"), - "id": "3f0075ad57ad603c83dc1e1a76aefcaf", - "_userId": userID, - "_groupId": groupID, - "createdTime": now.Format("2006-01-02T15:04:05.999+07:00"), - "_version": 0, - "_active": true, - "uploadId": "a21c82a5f5d2860add2539acded6b614", - "time": t.Format("2006-01-02T15:04:05.999+07:00"), - } -} - -// payload as a string rather than object or array -func dexG5MobDatumStringPayload(datum map[string]interface{}) map[string]interface{} { - datum["payload"] = `{"systemTime":"2017-11-05T18:56:51Z","transmitterId":"410X6M","transmitterTicks":5796922,"trend":"flat","trendRate":0.6,"trendRateUnits":"mg/dL/min"}` - datum["type"] = "cbg" - datum["units"] = "mmol/L" - datum["value"] = 8.1596 - return datum -} - -func omnipodPumpSettingsDatumTargetSet(datum map[string]interface{}) map[string]interface{} { - datum["type"] = "pumpSettings" - datum["activeSchedule"] = "Mine-2016" - datum["units"] = map[string]interface{}{"carb": "grams", "bg": "mg/dL"} - datum["basalSchedules"] = map[string]interface{}{ - "Mine-2016": []map[string]interface{}{ - {"rate": 0.5, "start": 0}, - {"rate": 1.35, "start": 55800000}, - }, - "camp 2015": []map[string]interface{}{ - {"rate": 0.5, "start": 0}, - {"rate": 1.35, "start": 55800000}, - }, - "weekend b": []map[string]interface{}{}, - } - datum["carbRatio"] = []map[string]interface{}{ - {"amount": 10, "start": 0}, - {"amount": 10, "start": 32400000}, - } - datum["insulinSensitivity"] = []map[string]interface{}{ - {"amount": 2.7753739955227665, "start": 0}, - {"amount": 2.7753739955227665, "start": 46800000}, - } - - datum["bgTarget"] = []map[string]interface{}{ - {"target": 5.550747991045533, "start": 0, "high": 7.2159723883591935}, - {"target": 5.550747991045533, "start": 46800000, "high": 7.2159723883591935}, - } - return datum -} - -func tandemWizardDatum(datum map[string]interface{}) map[string]interface{} { - datum["type"] = "wizard" - - datum["timezoneOffset"] = -300 - datum["clockDriftOffset"] = -221000 - datum["conversionOffset"] = 0 - datum["recommended"] = map[string]interface{}{ - "carb": 2, - "deliveryType": "scheduled", - "rate": 0.7, - } - - datum["bgInput"] = 4.440598392836427 - - datum["bgTarget"] = map[string]interface{}{ - "target": 4.440598392836427, - } - - datum["units"] = "mmol/L" - datum["duration"] = float64(300000) - datum["rate"] = 0.335 - datum["percent"] = 0.47857142857142865 - datum["conversionOffset"] = 0 - datum["bolus"] = "g2h6nohp5sdndpvl2l8kdete00lle4gt" - - return datum -} - -func alarmDeviceEventDatum(datum map[string]interface{}) map[string]interface{} { - datum["type"] = "deviceEvent" - datum["subType"] = "status" - datum["status"] = "suspended" - datum["reason"] = map[string]interface{}{ - "suspended": "automatic", - "resumed": "automatic", - } - return datum -} - -func cgmSettingsDatum(datum map[string]interface{}) map[string]interface{} { - datum["type"] = "cgmSettings" - datum["units"] = "mmol/L" - - datum["lowAlerts"] = map[string]interface{}{ - "enabled": true, - "level": 3.8855235937318735, - "snooze": 900000, - } - - datum["highAlerts"] = map[string]interface{}{ - "enabled": true, - "level": 22.202991964182132, - "snooze": 0, - } - - datum["rateOfChangeAlerts"] = map[string]interface{}{ - "fallRate": map[string]interface{}{ - "enabled": false, - "rate": -0.16652243973136602, - }, - "riseRate": map[string]interface{}{ - "enabled": false, - "rate": 0.16652243973136602, - }, - } - - datum["outOfRangeAlerts"] = map[string]interface{}{ - "enabled": true, - "snooze": 1200000, - } - return datum -} - -var makeJellyfishID = func(fields []string) string { - h := sha1.New() - hashFields := append(fields, "bootstrap") - for _, field := range hashFields { - io.WriteString(h, field) - io.WriteString(h, "_") - } - sha1 := h.Sum(nil) - id := strings.ToLower(base32.HexEncoding.WithPadding('-').EncodeToString(sha1)) - return id -} - -func BulkJellyfishData(deviceID string, groupID string, userID string, requiredRecords int) []map[string]interface{} { - data := []map[string]interface{}{} - twoWeeksAgo := time.Now().AddDate(0, 0, 14) - - for count := 0; count < requiredRecords; count++ { - typ := test.RandomChoice([]string{"cbg", "wizard", "deviceEvent"}) - dTime := twoWeeksAgo.Add(time.Duration(count) * time.Minute) - base := datumBase(deviceID, groupID, userID, dTime) - var datum map[string]interface{} - - switch typ { - case "cbg": - datum = dexG5MobDatumStringPayload(base) - case "cgmSettings": - datum = cgmSettingsDatum(base) - case "pumpSettings": - datum = omnipodPumpSettingsDatumTargetSet(base) - case "wizard": - datum = tandemWizardDatum(base) - case "deviceEvent": - datum = alarmDeviceEventDatum(base) - } - datum["_id"] = makeJellyfishID([]string{userID, deviceID, dTime.Format(time.RFC3339), typ}) - datum["id"] = datum["_id"] - data = append(data, datum) - } - return data -} - -func uploadDatum(datum map[string]interface{}, t time.Time) map[string]interface{} { - datum["type"] = "upload" - datum["computerTime"] = t.Format("2006-01-02T15:04:05") - datum["deviceTags"] = []string{ - "cgm", - "insulin-pump", - } - datum["deviceManufacturers"] = []string{ - "Medtronic", - } - datum["deviceModel"] = "MiniMed 530G 551" - datum["timeProcessing"] = "utc-bootstrapping" - return datum -} - -func BulkJellyfishUploadData(deviceID string, groupID string, userID string, requiredRecords int) []map[string]interface{} { - data := []map[string]interface{}{} - twoMonthsAgo := time.Now().AddDate(0, 2, 00) - for count := 0; count < requiredRecords; count++ { - typ := test.RandomChoice([]string{"cbg", "wizard", "deviceEvent"}) - dTime := twoMonthsAgo.Add(time.Duration(count) * time.Hour) - datum := uploadDatum(datumBase(deviceID, groupID, userID, dTime), dTime) - datum["_id"] = makeJellyfishID([]string{userID, deviceID, dTime.Format(time.RFC3339), typ}) - datum["id"] = datum["_id"] - data = append(data, datum) - } - return data -} diff --git a/migrations/20231128_jellyfish_migration/utils/utils_suite_test.go b/migrations/20231128_jellyfish_migration/utils/utils_suite_test.go deleted file mode 100644 index a7f980d288..0000000000 --- a/migrations/20231128_jellyfish_migration/utils/utils_suite_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package utils_test - -import ( - "testing" - - "github.com/tidepool-org/platform/test" -) - -func TestSuite(t *testing.T) { - test.Test(t) -} diff --git a/migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh b/migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh deleted file mode 100644 index c818a5ddeb..0000000000 --- a/migrations/20231128_jellyfish_migration/verify/cleanup_user_data.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -API_ENV=qa3.development -USER_ID_ONE=$1 -SERVER_TOKEN=$2 - -check_val() { - if [[ -z "$1" ]]; then - echo "missing $2 value" - exit 2 - fi -} - -check_val $USER_ID_ONE "USER_ID_ONE" - -if [[ -z "$SERVER_TOKEN" ]]; then - SECRET=$(op item get "qa3 server secret" --account tidepool.1password.com --fields label=credential --format json | jq -r '.value') - check_val $SECRET "SECRET" - SERVER_TOKEN="$(curl -s -I -X POST -H "X-Tidepool-Server-Secret: $SECRET" -H "X-Tidepool-Server-Name: devops" "https://${API_ENV}.tidepool.org/auth/serverlogin" | grep 'x-tidepool-session-token' | sed 's/[^:]*: //')" -fi - -check_val $SERVER_TOKEN "SERVER_TOKEN" - -http_response=$(curl -s -w "%{response_code}" --request DELETE \ - --url https://${API_ENV}.tidepool.org/v1/users/${USER_ID_ONE}/data \ - --header 'Accept: */*' \ - --header "X-Tidepool-Session-Token: $SERVER_TOKEN") - -echo "status $http_response deleting data for user $USER_ID_ONE" diff --git a/migrations/20231128_jellyfish_migration/verify/data_verify.go b/migrations/20231128_jellyfish_migration/verify/data_verify.go deleted file mode 100644 index a99375b4f1..0000000000 --- a/migrations/20231128_jellyfish_migration/verify/data_verify.go +++ /dev/null @@ -1,451 +0,0 @@ -package main - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "log" - "os" - "path/filepath" - - "github.com/r3labs/diff/v3" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" -) - -type DataVerify struct { - ctx context.Context - dataC *mongo.Collection -} - -func CompareDatasetDatums(platformData []map[string]interface{}, jellyfishData []map[string]interface{}, ignoredPaths ...string) (map[string]interface{}, error) { - diffs := map[string]interface{}{} - for id, platformDatum := range platformData { - if jellyfishData[id] == nil { - log.Println("no matching value in the jellyfish data") - break - } - changelog, err := diff.Diff(platformDatum, jellyfishData[id], diff.ConvertCompatibleTypes(), diff.StructMapKeySupport(), diff.AllowTypeMismatch(true), diff.FlattenEmbeddedStructs(), diff.SliceOrdering(false)) - if err != nil { - return nil, err - } - if len(changelog) > 0 { - if ignoredPaths != nil { - for _, path := range ignoredPaths { - changelog = changelog.FilterOut([]string{path}) - } - if len(changelog) == 0 { - continue - } - } - diffs[fmt.Sprintf("platform_%d", id)] = changelog - } - } - return diffs, nil -} - -func NewDataVerify(ctx context.Context, dataC *mongo.Collection) (*DataVerify, error) { - - if dataC == nil { - return nil, errors.New("missing required data collection") - } - - m := &DataVerify{ - ctx: ctx, - dataC: dataC, - } - - return m, nil -} - -var DatasetTypes = []string{"cbg", "smbg", "basal", "bolus", "deviceEvent", "wizard", "pumpSettings"} - -func (m *DataVerify) fetchDataSetNotDeduped(uploadID string, dataTypes []string) (map[string][]map[string]interface{}, error) { - if m.dataC == nil { - return nil, errors.New("missing data collection") - } - - typeSet := map[string][]map[string]interface{}{} - - for _, dType := range dataTypes { - - dset := []map[string]interface{}{} - - filter := bson.M{ - "uploadId": uploadID, - "type": dType, - "_active": true, - } - - sort := bson.D{{Key: "time", Value: 1}} - - if dType == "deviceEvent" || dType == "bolus" { - sort = bson.D{{Key: "time", Value: 1}, {Key: "subType", Value: 1}} - } - - dDataCursor, err := m.dataC.Find(m.ctx, filter, &options.FindOptions{ - Sort: sort, - }) - if err != nil { - return nil, err - } - defer dDataCursor.Close(m.ctx) - - if err := dDataCursor.All(m.ctx, &dset); err != nil { - return nil, err - } - log.Printf("got dataset [%s][%s][%d] results", uploadID, dType, len(dset)) - typeSet[dType] = dset - } - return typeSet, nil -} - -func (m *DataVerify) fetchDeviceData(userID string, deviceID string, dataTypes []string) (map[string][]map[string]interface{}, error) { - if m.dataC == nil { - return nil, errors.New("missing data collection") - } - - typeSet := map[string][]map[string]interface{}{} - - for _, dType := range dataTypes { - - dset := []map[string]interface{}{} - - filter := bson.M{ - "_userId": userID, - "deviceId": deviceID, - "type": dType, - } - - sort := bson.D{{Key: "time", Value: 1}} - - if dType == "deviceEvent" || dType == "bolus" { - sort = bson.D{{Key: "time", Value: 1}, {Key: "subType", Value: 1}} - } - - dDataCursor, err := m.dataC.Find(m.ctx, filter, &options.FindOptions{ - Sort: sort, - }) - if err != nil { - return nil, err - } - defer dDataCursor.Close(m.ctx) - - if err := dDataCursor.All(m.ctx, &dset); err != nil { - return nil, err - } - log.Printf("got device datasets [%s][%s][%d] results", deviceID, dType, len(dset)) - typeSet[dType] = dset - } - return typeSet, nil -} - -func (m *DataVerify) fetchDataSet(uploadID string, dataTypes []string) (map[string][]map[string]interface{}, error) { - if m.dataC == nil { - return nil, errors.New("missing data collection") - } - - typeSet := map[string][]map[string]interface{}{} - - for _, dType := range dataTypes { - - dset := []map[string]interface{}{} - - filter := bson.M{ - "uploadId": uploadID, - "type": dType, - } - - sort := bson.D{{Key: "time", Value: 1}} - - if dType == "deviceEvent" || dType == "bolus" { - sort = bson.D{{Key: "time", Value: 1}, {Key: "subType", Value: 1}} - } - - excludedFeilds := bson.M{ - // include to check dedup - // "_active": 0, - // "uploadId": 0, - "_archivedTime": 0, - "createdTime": 0, - "clockDriftOffset": 0, - "conversionOffset": 0, - "deduplicator": 0, - "_deduplicator": 0, - "_groupId": 0, - "guid": 0, - "_id": 0, - "id": 0, - "modifiedTime": 0, - "payload": 0, - "provenance": 0, - "revision": 0, - "_schemaVersion": 0, - "time": 0, - "timezoneOffset": 0, - "type": 0, - "_userId": 0, - "_version": 0, - } - - dDataCursor, err := m.dataC.Find(m.ctx, filter, &options.FindOptions{ - Sort: sort, - Projection: excludedFeilds, - }) - if err != nil { - return nil, err - } - defer dDataCursor.Close(m.ctx) - - if err := dDataCursor.All(m.ctx, &dset); err != nil { - return nil, err - } - log.Printf("got dataset [%s][%s][%d] results", uploadID, dType, len(dset)) - typeSet[dType] = dset - } - return typeSet, nil -} - -func (m *DataVerify) WriteBlobIDs() error { - if m.dataC == nil { - return errors.New("missing data collection") - } - - blobData := []map[string]interface{}{} - - dDataCursor, err := m.dataC.Find(m.ctx, bson.M{ - "deviceManufacturers": bson.M{"$in": []string{"Tandem", "Insulet"}}, - "client.private.blobId": bson.M{"$exists": true}, - "_active": true, - }, &options.FindOptions{ - Sort: bson.D{{Key: "deviceId", Value: 1}, {Key: "time", Value: 1}}, - Projection: bson.M{"_id": 0, "deviceId": 1, "blobId": "$client.private.blobId", "time": 1}, - }) - if err != nil { - return err - } - defer dDataCursor.Close(m.ctx) - - if err := dDataCursor.All(m.ctx, &blobData); err != nil { - return err - } - - type Blob struct { - DeviceID string `json:"deviceId"` - BlobID string `json:"blobId"` - } - - blobs := []Blob{} - - for _, v := range blobData { - blobs = append(blobs, Blob{ - BlobID: fmt.Sprintf("%v", v["blobId"]), - DeviceID: fmt.Sprintf("%v", v["deviceId"])}) - } - - blobPath := filepath.Join(".", "_blobs") - log.Printf("blob data written to %s", blobPath) - writeFileData(blobs, blobPath, "device_blobs.json", true) - return nil -} - -const ( - PlatformExtra = "extra" - PlatformDuplicate = "duplicate" - PlatformMissing = "missing" - - CompareDatasetsDepuplicatorKey = "_deduplicator" - CompareDatasetsDeviceTimeKey = "deviceTime" -) - -func CompareDatasets(dataSet []map[string]interface{}, baseSet []map[string]interface{}, datumKeyName string) map[string][]map[string]interface{} { - - diffs := map[string][]map[string]interface{}{ - PlatformExtra: {}, - PlatformDuplicate: {}, - PlatformMissing: {}, - } - - type deviceDataMap map[string][]map[string]interface{} - - baseSetMap := deviceDataMap{} - dataSetCounts := deviceDataMap{} - - for _, datum := range baseSet { - datumKey := fmt.Sprintf("%v", datum[datumKeyName]) - - if len(baseSetMap[datumKey]) == 0 { - baseSetMap[datumKey] = []map[string]interface{}{datum} - } else if len(baseSetMap[datumKey]) >= 1 { - baseSetMap[datumKey] = append(baseSetMap[datumKey], datum) - } - } - - for _, datum := range dataSet { - datumKey := fmt.Sprintf("%v", datum[datumKeyName]) - - if len(dataSetCounts[datumKey]) == 0 { - dataSetCounts[datumKey] = []map[string]interface{}{datum} - } else if len(dataSetCounts[datumKey]) >= 1 { - - currentItems := dataSetCounts[datumKey] - for _, item := range currentItems { - if fmt.Sprintf("%v", item) == fmt.Sprintf("%v", datum) { - diffs[PlatformDuplicate] = append(diffs[PlatformDuplicate], datum) - continue - } else { - diffs[PlatformExtra] = append(diffs[PlatformExtra], datum) - break - } - } - dataSetCounts[datumKey] = append(dataSetCounts[datumKey], datum) - } - if len(baseSetMap[fmt.Sprintf("%v", datum[datumKeyName])]) == 0 { - diffs[PlatformExtra] = append(diffs[PlatformExtra], datum) - } - } - - for datumKey, jDatums := range baseSetMap { - if len(dataSetCounts[datumKey]) < len(baseSetMap[datumKey]) { - //NOTE: more of an indicator there are missing records ... - for i := len(dataSetCounts[datumKey]); i < len(baseSetMap[datumKey]); i++ { - diffs[PlatformMissing] = append(diffs[PlatformMissing], jDatums[i]) - } - } - } - return diffs -} - -var dataTypePathIgnored = map[string][]string{ - "smbg": {"raw", "value"}, - "cbg": {"value"}, - "basal": {"rate"}, - "bolus": {"normal"}, -} - -func (m *DataVerify) VerifyUploadDifferences(platformUploadID string, jellyfishUploadID string, dataTyes []string, sameAccount bool) error { - - if len(dataTyes) == 0 { - dataTyes = DatasetTypes - } - - platformDataset, err := m.fetchDataSet(platformUploadID, dataTyes) - if err != nil { - return err - } - - jellyfishDataset, err := m.fetchDataSet(jellyfishUploadID, dataTyes) - if err != nil { - return err - } - - log.Printf("Compare platform[%s] vs jellyfish[%s]", platformUploadID, jellyfishUploadID) - - for dType, jfSet := range jellyfishDataset { - pfSet := platformDataset[dType] - comparePath := filepath.Join(".", "_compare", fmt.Sprintf("%s_%s", platformUploadID, jellyfishUploadID)) - log.Printf("data written to %s", comparePath) - - datumKeyName := CompareDatasetsDeviceTimeKey - if sameAccount { - datumKeyName = CompareDatasetsDepuplicatorKey - } - setDifferences := CompareDatasets(pfSet, jfSet, datumKeyName) - if len(setDifferences[PlatformMissing]) > 0 { - writeFileData(setDifferences[PlatformMissing], comparePath, fmt.Sprintf("%s_platform_missing.json", dType), true) - } - if len(setDifferences[PlatformDuplicate]) > 0 { - writeFileData(setDifferences[PlatformDuplicate], comparePath, fmt.Sprintf("%s_platform_duplicates.json", dType), true) - } - if len(setDifferences[PlatformExtra]) > 0 { - writeFileData(setDifferences[PlatformExtra], comparePath, fmt.Sprintf("%s_platform_extra.json", dType), true) - } - if len(pfSet) != len(jfSet) { - log.Printf("NOTE: datasets mismatch platform (%d) vs jellyfish (%d)", len(pfSet), len(jfSet)) - writeFileData(jfSet, comparePath, fmt.Sprintf("%s_jellyfish_datums.json", dType), true) - writeFileData(pfSet, comparePath, fmt.Sprintf("%s_platform_datums.json", dType), true) - break - } - differences, err := CompareDatasetDatums(pfSet, jfSet, dataTypePathIgnored[dType]...) - if err != nil { - return err - } - if len(differences) > 0 { - writeFileData(differences, comparePath, fmt.Sprintf("%s_datum_diff.json", dType), true) - } - } - return nil -} - -func (m *DataVerify) VerifyDeduped(uploadID string, dataTypes []string) error { - - if len(dataTypes) == 0 { - dataTypes = DatasetTypes - } - dataset, err := m.fetchDataSetNotDeduped(uploadID, dataTypes) - if err != nil { - return err - } - - if len(dataset) != 0 { - log.Printf("dataset should have been deduped but [%d] records are active", len(dataset)) - notDedupedPath := filepath.Join(".", "_not_deduped", uploadID) - for dType, dTypeItems := range dataset { - if len(dTypeItems) > 0 { - writeFileData(dTypeItems, notDedupedPath, fmt.Sprintf("%s_not_deduped_datums.json", dType), true) - } - } - } - return nil -} - -func (m *DataVerify) VerifyDeviceUploads(userID string, deviceID string, dataTypes []string) error { - - if len(dataTypes) == 0 { - dataTypes = DatasetTypes - } - datasets, err := m.fetchDeviceData(userID, deviceID, dataTypes) - if err != nil { - return err - } - - if len(datasets) != 0 { - deviceDataPath := filepath.Join(".", "_device_data", deviceID) - for dType, dTypeItems := range datasets { - if len(dTypeItems) > 0 { - writeFileData(dTypeItems, deviceDataPath, fmt.Sprintf("%s_data.json", dType), true) - } - } - } - return nil -} - -func writeFileData(data interface{}, path string, name string, asJSON bool) { - if data == nil || path == "" || name == "" { - return - } - - var handleErr = func(err error) { - if err != nil { - log.Println(err) - os.Exit(1) - } - } - - err := os.MkdirAll(path, os.ModePerm) - handleErr(err) - f, err := os.OpenFile(fmt.Sprintf("%s/%s", path, name), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - handleErr(err) - - defer f.Close() - - if asJSON { - jsonData, err := json.Marshal(data) - handleErr(err) - f.WriteString(string(jsonData) + "\n") - return - } - f.WriteString(fmt.Sprintf("%v", data)) -} diff --git a/migrations/20231128_jellyfish_migration/verify/data_verify_test.go b/migrations/20231128_jellyfish_migration/verify/data_verify_test.go deleted file mode 100644 index 5e2b72965e..0000000000 --- a/migrations/20231128_jellyfish_migration/verify/data_verify_test.go +++ /dev/null @@ -1,161 +0,0 @@ -package main_test - -import ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "github.com/r3labs/diff/v3" - - "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/verify/test" - - verify "github.com/tidepool-org/platform/migrations/20231128_jellyfish_migration/verify" -) - -var _ = Describe("DataVerify", func() { - - var _ = Describe("CompareDatasetDatums", func() { - - var datasetOne = []map[string]interface{}{} - var datasetTwo = []map[string]interface{}{} - - BeforeEach(func() { - - datasetOne = []map[string]interface{}{ - { - "one": 1, - "value": 2, - }, - { - "three": 3, - "more": true, - }, - } - - datasetTwo = []map[string]interface{}{ - { - "one": "one", - "value": 2, - }, - { - "three": 3, - "more": false, - }, - } - - }) - - It("will genterate a list of differences between two datasets", func() { - changes, err := verify.CompareDatasetDatums(datasetOne, datasetTwo) - Expect(err).To(BeNil()) - Expect(changes).ToNot(BeEmpty()) - }) - - It("will genterate no differences when the datasets are the same ", func() { - changes, err := verify.CompareDatasetDatums(datasetOne, datasetOne) - Expect(err).To(BeNil()) - Expect(changes).To(BeEmpty()) - }) - - It("changes will contain each diff", func() { - changes, err := verify.CompareDatasetDatums(datasetOne, datasetTwo) - Expect(err).To(BeNil()) - Expect(changes).To(Equal(map[string]interface{}{ - "platform_0": diff.Changelog{{Type: diff.UPDATE, Path: []string{"one"}, From: 1, To: "one"}}, - "platform_1": diff.Changelog{{Type: diff.UPDATE, Path: []string{"more"}, From: true, To: false}}, - })) - }) - - It("can filter based on path", func() { - changes, err := verify.CompareDatasetDatums(datasetOne, datasetTwo, "more") - Expect(err).To(BeNil()) - Expect(changes).To(Equal(map[string]interface{}{ - "platform_0": diff.Changelog{{Type: diff.UPDATE, Path: []string{"one"}, From: 1, To: "one"}}, - })) - }) - - It("can filter multiple based on path", func() { - changes, err := verify.CompareDatasetDatums(datasetOne, datasetTwo, "more", "one") - Expect(err).To(BeNil()) - Expect(changes).To(BeEmpty()) - }) - - }) - var _ = Describe("CompareDatasets", func() { - - It("will have no differences when that same and no dups", func() { - dSetDifference := verify.CompareDatasets(test.JFBolusSet, test.JFBolusSet, verify.CompareDatasetsDeviceTimeKey) - Expect(len(dSetDifference[verify.PlatformDuplicate])).To(Equal(0)) - Expect(len(dSetDifference[verify.PlatformExtra])).To(Equal(0)) - Expect(len(dSetDifference[verify.PlatformMissing])).To(Equal(0)) - }) - - It("will find duplicates in the platform dataset", func() { - dSetDifference := verify.CompareDatasets(test.PlatformBolusSet, test.JFBolusSet, verify.CompareDatasetsDeviceTimeKey) - Expect(len(dSetDifference[verify.PlatformDuplicate])).To(Equal(395)) - Expect(len(dSetDifference[verify.PlatformExtra])).To(Equal(0)) - Expect(len(dSetDifference[verify.PlatformMissing])).To(Equal(0)) - }) - - It("will find extras in the platform dataset that have duplicate timestamp but not data", func() { - duplicateTimeStamp := map[string]interface{}{ - "extra": true, - "deviceTime": "2018-01-03T13:07:10", - } - - dSetDifference := verify.CompareDatasets(append(test.PlatformBolusSet, duplicateTimeStamp), test.JFBolusSet, verify.CompareDatasetsDeviceTimeKey) - Expect(len(dSetDifference[verify.PlatformDuplicate])).To(Equal(395)) - Expect(len(dSetDifference[verify.PlatformExtra])).To(Equal(1)) - Expect(len(dSetDifference[verify.PlatformMissing])).To(Equal(0)) - }) - - It("will find extras in the platform dataset", func() { - expectedExtra := map[string]interface{}{ - "extra": 3, - "deviceTime": "2023-01-18T12:00:00", - } - - dSetDifference := verify.CompareDatasets(append(test.PlatformBolusSet, expectedExtra), test.JFBolusSet, verify.CompareDatasetsDeviceTimeKey) - Expect(len(dSetDifference[verify.PlatformDuplicate])).To(Equal(395)) - Expect(len(dSetDifference[verify.PlatformExtra])).To(Equal(1)) - Expect(dSetDifference[verify.PlatformExtra][0]).To(Equal(expectedExtra)) - Expect(len(dSetDifference[verify.PlatformMissing])).To(Equal(0)) - }) - - It("will find datums that are missing in the platform dataset", func() { - platformBasals := test.GetPlatformBasalData() - jellyfishBasals := test.GetJFBasalData() - - Expect(len(platformBasals)).To(Equal(3123)) - Expect(len(jellyfishBasals)).To(Equal(3386)) - - dSetDifference := verify.CompareDatasets(platformBasals, jellyfishBasals, verify.CompareDatasetsDeviceTimeKey) - Expect(len(dSetDifference[verify.PlatformDuplicate])).To(Equal(5)) - Expect(len(dSetDifference[verify.PlatformExtra])).To(Equal(4)) - Expect(len(dSetDifference[verify.PlatformMissing])).To(Equal(263)) - }) - - It("will find datums that are missing in the platform dataset with deduplicator key", func() { - platformSMBGs := test.GetPlatformSMBGData() - jfSMBGs := test.GetJellyfishSMBGData() - - Expect(len(platformSMBGs)).To(Equal(11)) - Expect(len(jfSMBGs)).To(Equal(11)) - - dSetDifference := verify.CompareDatasets(platformSMBGs, jfSMBGs, verify.CompareDatasetsDepuplicatorKey) - Expect(len(dSetDifference[verify.PlatformDuplicate])).To(Equal(0)) - Expect(len(dSetDifference[verify.PlatformExtra])).To(Equal(11)) - Expect(len(dSetDifference[verify.PlatformMissing])).To(Equal(11)) - }) - - It("will match when datasets are the same using with deduplicator key", func() { - smbgs := test.GetPlatformSMBGData() - - Expect(len(smbgs)).To(Equal(11)) - - dSetDifference := verify.CompareDatasets(smbgs, smbgs, verify.CompareDatasetsDepuplicatorKey) - Expect(len(dSetDifference[verify.PlatformDuplicate])).To(Equal(0)) - Expect(len(dSetDifference[verify.PlatformExtra])).To(Equal(0)) - Expect(len(dSetDifference[verify.PlatformMissing])).To(Equal(0)) - }) - - }) -}) diff --git a/migrations/20231128_jellyfish_migration/verify/fetch_blobs.sh b/migrations/20231128_jellyfish_migration/verify/fetch_blobs.sh deleted file mode 100644 index d5c9126a1b..0000000000 --- a/migrations/20231128_jellyfish_migration/verify/fetch_blobs.sh +++ /dev/null @@ -1,81 +0,0 @@ -#!/bin/bash -JSON_FILE=$1 -OUTPUT_DIR=$2 -LOG_PREFIX=prod_blob_series - -check_val() { - if [[ -z "$1" ]]; then - echo "missing $2 value" - exit 2 - fi -} - -## PRD -SECRET=$(op item get "PRD Server Secret" --account tidepool.1password.com --fields label=credential --format json | jq -r '.value') -API_ENV=api - -## QA -# SECRET=$(op item get "qa3 server secret" --account tidepool.1password.com --fields label=credential --format json | jq -r '.value') -# API_ENV=qa2.development - -check_val $JSON_FILE "JSON_FILE" -check_val $OUTPUT_DIR "OUTPUT_DIR" -check_val $SECRET "SECRET" - -SESSION_TOKEN="$(curl -s -I -X POST -H "X-Tidepool-Server-Secret: $SECRET" -H "X-Tidepool-Server-Name: devops" "https://${API_ENV}.tidepool.org/auth/serverlogin" | grep 'x-tidepool-session-token' | sed 's/[^:]*: //')" - -check_val $SESSION_TOKEN "SESSION_TOKEN" - - -## enbale downloading o -counter=0 - -jq -c ' reverse .[]' $JSON_FILE | while read i; do - - # counter=$((counter+1)) - - # # if [[ "$counter" == 2 ]]; then - # # # reset counter - # # counter=0 - - DEVICE_ID=$(jq -r '.deviceId' <<<"$i") - check_val $DEVICE_ID "DEVICE_ID" - - BLOB_ID=$(jq -r '.blobId' <<<"$i") - check_val $BLOB_ID "BLOB_ID" - - if [[ "$DEVICE_ID" =~ .*"tandem".* ]]; then - OUTPUT_FILE="$OUTPUT_DIR/$DEVICE_ID/$BLOB_ID"_blob.gz - else - OUTPUT_FILE="$OUTPUT_DIR/$DEVICE_ID/$BLOB_ID"_blob.ibf - fi - - # is already downloaded? - if grep -wq "$OUTPUT_FILE" "${LOG_PREFIX}_upload.log" || grep -wq "$OUTPUT_FILE" "${LOG_PREFIX}_error.log"; then - echo "$OUTPUT_FILE already downloaded" - else - - mkdir -p "$OUTPUT_DIR/$DEVICE_ID" - - check_val $OUTPUT_FILE "OUTPUT_FILE" - - - http_response=$(curl -s -o $OUTPUT_FILE -w "%{response_code}" --request GET \ - --url https://${API_ENV}.tidepool.org/v1/blobs/${BLOB_ID}/content \ - --header 'Accept: */*' \ - --header "X-Tidepool-Session-Token: $SESSION_TOKEN") - - if [ $http_response != "200" ]; then - echo "$http_response error downloading blob $BLOB_ID for device $DEVICE_ID" - rm -rf $OUTPUT_FILE - else - if [[ "$DEVICE_ID" =~ .*"tandem".* ]]; then - echo "status $http_response done downloading tandem blob $OUTPUT_FILE" - else - gzip $OUTPUT_FILE - echo "status $http_response done downloading omnipod blob $OUTPUT_FILE" - fi - fi - fi - # fi -done diff --git a/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh b/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh deleted file mode 100644 index da848d4f08..0000000000 --- a/migrations/20231128_jellyfish_migration/verify/process_all_blobs.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -USER_ID=6a452338-5064-4795-81ca-84957bad2280 -USER_EMAIL=jamie+platform_upload@tidepool.org -USER_PW=$1 -LOG_PREFIX=qa_blob - -DEVICE_TYPE=$2 -if [[ -z "$DEVICE_TYPE" ]]; then - DEVICE_TYPE=tandem - USER_ID=04afa5f8-9cb4-4824-9d76-67fa8740da2b - USER_EMAIL=jamie+jellyfish_upload@tidepool.org -fi - -BLOBS_DIR=~/Documents/tmp/prd_blobs/${DEVICE_TYPE} -SECRET=$(op item get "qa3 server secret" --account tidepool.1password.com --fields label=credential --format json | jq -r '.value') - -for filename in $BLOBS_DIR*/*blob*.gz; do - - if grep -wq "$filename" "${LOG_PREFIX}_upload.log"; then - echo "$filename already uploaded so cleaning up" - file_path=$(echo $filename | rev | cut -d"/" -f2- | rev) - rm -rf "$file_path" - echo "$file_path removed" - elif grep -wq "$filename" "${LOG_PREFIX}_error.log"; then - echo "$filename already failed to upload" - else - SERVER_TOKEN="$(curl -s -I -X POST -H "X-Tidepool-Server-Secret: $SECRET" -H "X-Tidepool-Server-Name: devops" "https://${API_ENV}.tidepool.org/auth/serverlogin" | grep 'x-tidepool-session-token' | sed 's/[^:]*: //')" - source ./upload_blob.sh "$filename" "$USER_EMAIL" "$USER_PW" "$LOG_PREFIX" - source ./cleanup_user_data.sh "$USER_ID" "$SERVER_TOKEN" - fi -done diff --git a/migrations/20231128_jellyfish_migration/verify/test/data_verify.go b/migrations/20231128_jellyfish_migration/verify/test/data_verify.go deleted file mode 100644 index 8a10be74b3..0000000000 --- a/migrations/20231128_jellyfish_migration/verify/test/data_verify.go +++ /dev/null @@ -1,81720 +0,0 @@ -package test - -import "encoding/json" - -var JFBolusSet = []map[string]interface{}{ - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T05:48:32", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T08:48:43", - "normal": 2.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T17:07:35", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T17:48:17", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T22:16:32", - "expectedNormal": 6, - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T02:48:01", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T02:57:56", - "normal": 2.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T03:45:23", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T04:02:33", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T04:07:54", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T12:10:52", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T13:43:31", - "normal": 0.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T18:55:53", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T22:06:00", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-13T00:07:54", - "normal": 6.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-13T15:36:15", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-13T19:15:32", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-13T23:32:46", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-14T02:56:18", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-14T15:05:16", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-14T18:45:59", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-14T21:06:30", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T02:10:44", - "expectedNormal": 6, - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T10:11:52", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T10:21:08", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T10:52:13", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T18:51:32", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T20:32:07", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T20:43:33", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T21:26:55", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T07:56:57", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T15:32:09", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:04:19", - "expectedNormal": 3.7, - "normal": 0.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:04:45", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:23:41", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:35:34", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:58:46", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T22:04:48", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T07:49:22", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T07:58:22", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T08:31:44", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T09:25:59", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T15:19:35", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T15:41:16", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T16:13:32", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T16:51:39", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T17:36:34", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T22:24:30", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T00:26:16", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T00:57:05", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T09:39:10", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T13:26:16", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T15:56:31", - "normal": 0.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T16:46:24", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T17:16:59", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T01:21:09", - "normal": 2.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T01:51:44", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T18:01:16", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T19:01:35", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T22:24:42", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T22:27:54", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T23:16:39", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T11:50:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T13:36:40", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T18:31:12", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T19:04:49", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T19:13:53", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-21T14:16:39", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T00:12:03", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T13:54:39", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T20:02:33", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T20:09:02", - "normal": 7.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T20:42:46", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T20:51:20", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-23T14:51:38", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-23T17:40:56", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T10:57:40", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T13:49:15", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T20:29:08", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T23:20:14", - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T02:11:25", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T03:41:15", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T03:49:26", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T11:34:54", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T11:36:30", - "expectedNormal": 3.7, - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T11:39:54", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T18:55:44", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T21:00:32", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T21:56:23", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T22:40:16", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T00:47:19", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T11:19:24", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T18:22:46", - "normal": 9.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T20:06:31", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T21:00:39", - "normal": 4.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T00:43:11", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T00:54:23", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T01:21:34", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T07:02:47", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T08:20:19", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T11:57:25", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T18:36:04", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T20:18:11", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T10:55:51", - "normal": 10.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T13:31:27", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T17:47:15", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T18:58:25", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T20:20:09", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T05:47:36", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T11:04:51", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T11:17:10", - "expectedNormal": 5, - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T11:17:44", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T11:59:21", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T12:33:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T16:04:51", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T18:22:02", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T20:35:15", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T00:19:10", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T01:14:53", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T11:38:04", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T14:10:30", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T18:11:40", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T19:40:37", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T22:39:58", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T09:55:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T12:02:23", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T12:11:07", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T15:03:11", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T23:36:08", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-02T13:42:27", - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T08:36:32", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T12:46:16", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T14:31:00", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T19:01:03", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T19:13:12", - "duration": 3600000, - "extended": 1.35, - "normal": 3.25, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T23:09:17", - "expectedNormal": 5.6, - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-04T01:32:34", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-04T13:31:48", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-04T23:45:20", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-05T05:38:22", - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-05T13:05:36", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-05T18:04:44", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-05T22:31:49", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-06T09:05:49", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-06T19:44:34", - "normal": 3.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-07T11:30:47", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-07T17:39:58", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T09:36:46", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T12:09:06", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T13:51:33", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T22:47:22", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T23:06:37", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T23:34:05", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T11:51:03", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T18:28:48", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T18:41:43", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T19:46:42", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T22:41:34", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T03:05:28", - "normal": 1.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T11:34:38", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T14:55:50", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T15:23:08", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T19:28:56", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T21:16:11", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T22:17:25", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-11T14:30:42", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-11T19:17:18", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T13:15:43", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T14:37:19", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T20:45:23", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T21:17:50", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T22:07:50", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T23:57:33", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-13T10:28:04", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-13T17:42:12", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T04:31:16", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T09:40:01", - "normal": 3.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T15:57:40", - "normal": 2.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T17:26:58", - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T05:49:43", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T09:42:54", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T15:42:11", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T17:58:05", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T20:36:40", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T21:54:57", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T02:10:54", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T05:18:35", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T17:03:43", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T21:17:40", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T21:27:12", - "expectedNormal": 1.8, - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-17T15:02:37", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-18T08:53:51", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-18T14:07:21", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-19T00:37:12", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-20T22:52:22", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-21T16:04:44", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-21T17:31:36", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-22T20:34:13", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T00:32:29", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T02:01:53", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T13:25:12", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T14:45:29", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T15:17:41", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T15:27:27", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T20:51:42", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T22:28:05", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-24T15:45:49", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-24T17:30:54", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T03:24:31", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T17:51:24", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T18:17:02", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T18:44:42", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T19:06:09", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-26T04:38:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-26T21:52:20", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-26T22:10:35", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T00:35:55", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T12:09:08", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T13:12:31", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T22:06:04", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T23:57:59", - "normal": 8.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T13:41:05", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T21:53:48", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T22:38:58", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T23:35:34", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T01:10:10", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T13:28:49", - "normal": 7.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T15:31:09", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T15:47:25", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T20:49:26", - "normal": 10.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T23:31:22", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T01:14:51", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T10:07:54", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T14:41:41", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T15:36:28", - "normal": 0.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T17:21:07", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T17:47:07", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T19:43:22", - "normal": 10.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T21:42:19", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T23:34:45", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T23:57:13", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T14:15:24", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T15:37:20", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T16:37:23", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T20:22:35", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T22:50:28", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T00:18:37", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T03:28:56", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T08:23:20", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T17:09:58", - "normal": 5.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T20:29:55", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T21:39:29", - "normal": 11.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T01:37:45", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T09:05:27", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T09:28:02", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T15:17:44", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T17:05:07", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T21:57:29", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T22:31:41", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T23:58:14", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T06:23:16", - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T13:07:10", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T17:36:24", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T19:19:53", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-04T20:39:32", - "normal": 12.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-04T23:27:30", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-05T11:26:40", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-05T14:39:47", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-05T21:24:08", - "normal": 12.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-05T23:47:57", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-06T10:29:13", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-07T02:43:11", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-07T15:29:23", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-07T15:53:38", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T00:50:58", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T02:22:40", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T10:49:22", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T12:10:15", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T16:06:15", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T21:00:55", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T22:52:11", - "normal": 13.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T06:48:05", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T11:57:20", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T14:50:09", - "expectedNormal": 7.1, - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T15:09:57", - "expectedNormal": 5.3, - "normal": 0, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T15:10:07", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T15:45:24", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T19:08:06", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T00:20:48", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T09:57:07", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T15:19:38", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T19:51:35", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T21:04:03", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-11T17:21:27", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-11T23:50:01", - "normal": 9.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-12T14:21:27", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T01:22:50", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T09:16:42", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T09:45:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T17:59:12", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T19:51:42", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T01:09:36", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T15:27:34", - "normal": 6.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T15:37:30", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T19:52:15", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T22:44:38", - "normal": 11, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T23:04:59", - "expectedNormal": 8.7, - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-15T08:08:01", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-15T17:50:26", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-15T18:22:34", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-15T22:12:43", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-16T05:28:57", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-16T19:06:03", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-18T00:44:27", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-18T15:16:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-18T21:34:19", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-19T15:18:48", - "normal": 7.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-19T18:24:25", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-19T21:40:18", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T01:57:09", - "normal": 5.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T05:21:15", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T14:43:26", - "normal": 2.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T20:23:29", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T23:15:21", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-21T01:47:25", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-21T16:32:58", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-21T21:12:41", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-22T13:07:23", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-22T13:24:37", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-22T13:38:43", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-22T14:23:46", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T00:01:17", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T02:53:10", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T10:26:09", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T12:45:53", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T19:04:33", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T02:03:30", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T08:42:05", - "normal": 3.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T09:11:28", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T13:05:25", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T16:20:41", - "normal": 0.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T19:39:24", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T22:58:57", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-25T09:05:32", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-25T09:15:49", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-25T10:05:32", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-25T15:20:46", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-26T00:34:00", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-26T00:40:32", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-26T17:42:21", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-27T00:26:46", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-27T01:56:53", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-27T15:00:57", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-27T16:30:36", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T00:07:24", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T04:04:35", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T11:06:58", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T12:05:56", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T17:32:14", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T22:51:31", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-29T09:24:11", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-29T11:48:49", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-31T17:35:53", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-01T22:39:45", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-01T23:11:22", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-02T05:32:22", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-02T13:53:59", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-02T15:01:02", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-03T11:47:19", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-03T17:52:13", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-04T00:51:30", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-04T01:35:03", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-04T10:23:28", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-05T00:40:31", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-05T22:10:18", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T00:30:31", - "duration": 9000000, - "extended": 2.4, - "normal": 0.1, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T11:27:46", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T12:24:47", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T21:00:06", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T21:26:09", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T22:30:08", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-07T01:20:24", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-07T15:08:42", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-07T17:35:21", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T00:40:52", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T04:05:56", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T04:08:07", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T20:24:34", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T21:17:19", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-09T03:41:21", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-09T03:43:00", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-09T15:27:27", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-09T16:50:23", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-10T00:06:05", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-10T07:13:02", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-10T10:23:08", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T01:16:30", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T13:20:10", - "normal": 1.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T17:04:18", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T19:38:24", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T20:40:19", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T22:22:57", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T23:03:25", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T10:31:15", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T10:47:00", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T17:15:24", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T22:52:54", - "duration": 5400000, - "extended": 3.6, - "normal": 0.4, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T23:37:16", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-13T03:06:20", - "expectedNormal": 2.4, - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-13T04:51:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-13T19:40:33", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-13T20:05:03", - "normal": 0.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-14T17:20:11", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-14T17:56:34", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-15T01:56:38", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-15T17:29:22", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-16T09:23:19", - "normal": 2.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-17T11:56:27", - "normal": 0.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T00:34:51", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T04:32:23", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T12:15:36", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T12:56:37", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T20:43:52", - "normal": 9.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T03:06:10", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T17:37:52", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T18:33:24", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T22:24:06", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T23:15:16", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T23:57:50", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T11:27:44", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T12:13:32", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T17:12:58", - "normal": 7.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T23:25:38", - "normal": 4.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-21T18:12:48", - "normal": 4.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-21T23:02:43", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-22T05:11:08", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-22T12:46:46", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-22T18:44:55", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-22T23:47:30", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-23T15:22:30", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T01:28:13", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T04:50:59", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T10:06:16", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T10:57:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T16:20:38", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T20:57:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T21:10:06", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T01:46:05", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T03:01:41", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T12:45:34", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T16:35:50", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T16:43:09", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-26T14:50:38", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-26T23:18:20", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-27T19:10:37", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-27T19:56:05", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-27T20:05:22", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-27T20:33:26", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-01T11:06:45", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-01T13:38:00", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-01T17:26:06", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T05:10:59", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T14:53:50", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T15:15:41", - "duration": 7200000, - "extended": 4, - "normal": 2.65, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T17:55:24", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T21:27:07", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-03T02:23:28", - "normal": 3.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-03T07:55:24", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-03T13:31:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-03T17:33:40", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T01:00:34", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T09:51:54", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T13:59:53", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T14:53:15", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T17:26:51", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T19:38:13", - "normal": 8.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T23:09:52", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T23:57:26", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-05T03:09:50", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-05T14:54:46", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-05T18:29:31", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-06T00:34:35", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-06T01:21:36", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-06T06:12:45", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-06T19:38:19", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T08:26:18", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T10:24:27", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T16:59:43", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T22:10:21", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T23:47:40", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-08T00:47:32", - "duration": 10800000, - "extended": 1.65, - "subType": "square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-08T17:20:24", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-08T23:16:45", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-09T09:43:12", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-09T19:36:18", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-09T21:47:07", - "normal": 11, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-09T22:28:29", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T00:56:27", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T05:18:33", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T10:09:03", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T19:08:41", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T19:30:42", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T21:00:08", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T21:11:26", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T00:12:25", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T03:50:32", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T09:48:55", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T17:56:25", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T21:45:42", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T23:48:21", - "normal": 7.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T23:59:24", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-12T11:02:19", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-12T14:13:44", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-12T23:30:03", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-13T00:01:21", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-13T08:23:02", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-13T15:29:58", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-13T16:25:10", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T01:00:14", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T01:48:33", - "duration": 7200000, - "extended": 5, - "subType": "square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T08:26:33", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T09:15:40", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T21:17:36", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T21:36:42", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T01:00:44", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T12:10:00", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T13:36:53", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T21:24:43", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T22:46:02", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-16T19:49:33", - "normal": 12.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-17T15:56:01", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-18T10:02:04", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-18T15:29:15", - "normal": 6.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-18T16:27:25", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-18T21:15:02", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-19T06:28:44", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-19T15:28:25", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-19T22:15:08", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T08:14:49", - "duration": 3600000, - "extended": 1.5, - "normal": 0.5, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T12:02:19", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T13:19:06", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T16:07:19", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T19:43:27", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T20:56:53", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-21T00:32:48", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-21T14:39:05", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-21T21:09:21", - "normal": 12, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-21T22:14:04", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T03:19:52", - "expectedNormal": 5.15, - "normal": 0.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T03:20:35", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T10:57:48", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T16:15:49", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T23:32:14", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T03:44:48", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T10:03:49", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T12:03:21", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T12:08:31", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T17:28:19", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T18:10:06", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T22:45:10", - "normal": 6.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T23:57:11", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T01:52:51", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T04:04:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T10:09:10", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T15:22:15", - "normal": 9.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T15:59:21", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T18:45:12", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T03:44:15", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T04:12:56", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T13:25:50", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T15:47:08", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T16:27:53", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T17:26:51", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T01:03:51", - "normal": 9.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T04:48:39", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T15:52:08", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T18:11:28", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T21:42:00", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T23:21:43", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-27T13:11:38", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-27T13:27:58", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-27T13:43:12", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-27T14:19:41", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-28T01:21:26", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-28T02:49:55", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-28T12:09:39", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-28T21:12:56", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T01:42:57", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T12:10:07", - "normal": 8.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T20:29:43", - "normal": 8.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T23:08:20", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T23:23:56", - "expectedNormal": 2, - "normal": 0.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T23:24:13", - "expectedNormal": 3.8, - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T23:25:03", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-30T09:17:33", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-30T11:41:40", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-30T18:46:16", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-30T22:26:35", - "normal": 7.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-31T09:34:04", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-31T11:02:09", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-31T18:03:31", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-01T13:35:12", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-01T19:00:43", - "expectedNormal": 5.5, - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-02T11:24:01", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T00:24:02", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T04:46:03", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T13:58:14", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T15:41:52", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T22:48:16", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T22:53:19", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T23:37:06", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T17:49:44", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T18:25:58", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T20:06:51", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T20:50:31", - "expectedNormal": 6.5, - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T21:47:42", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T11:10:22", - "normal": 8.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T13:57:52", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T14:41:02", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T19:55:35", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T20:07:23", - "normal": 6.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T23:10:52", - "normal": 10.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-06T17:04:13", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T00:30:35", - "normal": 13, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T11:30:23", - "expectedNormal": 11.3, - "normal": 7.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T13:39:36", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T15:31:20", - "normal": 7.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T17:03:27", - "normal": 6.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T19:36:38", - "normal": 11.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T02:04:38", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T11:36:22", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T15:35:43", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T16:36:54", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T17:06:19", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T18:36:43", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T20:45:53", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T21:43:56", - "normal": 5.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T22:27:26", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-09T13:34:32", - "normal": 4.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-09T23:51:42", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T11:33:52", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T15:06:31", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T16:39:01", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T23:28:10", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T23:56:06", - "normal": 3.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-11T08:31:34", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-11T14:14:04", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-11T21:33:10", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-12T13:11:06", - "normal": 5.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-12T15:22:32", - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-12T20:37:48", - "duration": 3600000, - "extended": 1.4, - "normal": 4.1, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T07:00:52", - "normal": 2.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T11:55:34", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T15:38:33", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T16:43:21", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T22:25:40", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T23:43:31", - "duration": 3600000, - "extended": 3, - "normal": 4.5, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T07:24:30", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T11:26:07", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T14:02:33", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T16:13:29", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T16:21:37", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-15T04:30:42", - "normal": 2.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-15T11:27:28", - "normal": 9.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-15T21:09:40", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-15T21:29:47", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T08:42:28", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T09:08:02", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T18:50:11", - "normal": 7.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T22:19:29", - "normal": 8.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T07:49:58", - "expectedNormal": 6.25, - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T10:22:10", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T15:38:57", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T16:53:15", - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T23:01:44", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T23:17:46", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-18T03:36:54", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-18T08:15:40", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-18T13:03:08", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-18T22:49:11", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-19T10:49:57", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-19T12:47:07", - "normal": 7.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-19T18:51:49", - "normal": 0.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T00:34:12", - "normal": 4.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T11:55:56", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T12:21:25", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T12:25:59", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T12:40:44", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T16:51:52", - "normal": 5.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T17:13:53", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T18:53:57", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T21:13:02", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T21:17:28", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T22:56:20", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T05:00:30", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T14:57:12", - "expectedNormal": 5.7, - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T17:25:57", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T19:55:14", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T20:21:02", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T20:48:12", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T23:36:01", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T00:17:02", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T07:20:00", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T09:32:51", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T15:34:54", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T17:17:07", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T18:33:33", - "normal": 8.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T19:56:36", - "normal": 4.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T21:38:22", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T14:44:27", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T16:39:55", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T17:17:36", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T18:45:04", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T21:54:57", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T23:08:34", - "expectedNormal": 2.5, - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T23:30:54", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T10:55:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T16:10:07", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T18:45:06", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T21:29:29", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-25T02:05:38", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-25T16:31:35", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-25T16:52:59", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-25T23:23:29", - "normal": 9.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T10:15:03", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T13:15:18", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T13:53:04", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T15:43:54", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T20:06:36", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-27T12:42:46", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-27T15:48:19", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-27T15:53:18", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-27T23:14:39", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T02:49:38", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T14:15:39", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T15:36:19", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T17:22:40", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T23:33:46", - "normal": 6.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-29T12:43:56", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-29T14:24:57", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-29T16:00:35", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-29T22:51:00", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-30T16:41:59", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-30T23:51:20", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-01T00:40:06", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-01T02:19:29", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-01T15:47:28", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-01T17:58:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T01:01:32", - "duration": 5400000, - "extended": 1.85, - "normal": 0.05, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T14:35:54", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T16:30:55", - "normal": 1.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T18:03:13", - "normal": 2.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T18:30:32", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T22:44:03", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-03T13:28:40", - "normal": 7.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-03T22:38:40", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T06:40:11", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T12:09:02", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T12:42:38", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T13:58:04", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T19:31:20", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-05T13:12:58", - "normal": 5.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-05T17:02:00", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-05T22:18:24", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-06T12:34:16", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-06T20:28:21", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-06T21:05:28", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-07T10:11:40", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-07T12:47:09", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-07T20:59:51", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-07T21:46:06", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-08T07:29:03", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-08T13:44:00", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-08T20:00:38", - "normal": 2.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-09T14:28:06", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-09T23:50:14", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T10:13:12", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T12:28:54", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T14:38:18", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T18:48:40", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T19:22:11", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T20:10:02", - "normal": 0.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T20:43:41", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T02:11:06", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T15:22:52", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T19:51:32", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T20:01:17", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T21:07:27", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T22:40:53", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T00:51:28", - "normal": 5.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T09:31:50", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T17:24:32", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T17:31:58", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T19:20:54", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T20:09:19", - "normal": 6.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T23:53:39", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T06:04:08", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T09:33:30", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T10:02:35", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T13:25:22", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T14:39:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T21:27:31", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T21:49:54", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-14T06:30:45", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-14T17:13:50", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-14T19:51:30", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T02:59:12", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T18:34:17", - "normal": 8.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T20:03:48", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T20:13:10", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T21:08:56", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T21:38:31", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T11:44:10", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T13:54:41", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T17:33:07", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T18:59:52", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T22:40:06", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T10:47:43", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T17:33:07", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T21:09:30", - "normal": 8.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T21:38:23", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-18T14:40:29", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-18T16:20:15", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-18T17:18:29", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-18T21:04:49", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T08:29:53", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T10:55:07", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T13:03:51", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T20:15:44", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T20:28:37", - "normal": 10.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T00:18:39", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T01:24:17", - "normal": 0.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T07:49:45", - "normal": 0.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T11:51:55", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T12:13:22", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T14:57:44", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T18:03:00", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T10:31:41", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T13:57:19", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T19:23:59", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T22:46:23", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-22T09:51:09", - "normal": 9.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-22T19:41:23", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-22T22:49:19", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T07:43:22", - "normal": 5.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T15:05:51", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T16:43:30", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T20:24:21", - "normal": 10.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T20:36:41", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T01:31:04", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T12:17:15", - "normal": 4.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T13:52:54", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T22:00:26", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T22:31:42", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T07:08:36", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T09:25:26", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T10:43:07", - "duration": 3600000, - "extended": 2.15, - "normal": 6.35, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T15:29:54", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T19:28:58", - "normal": 4.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T21:48:56", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T07:47:05", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T15:09:57", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T15:23:19", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T19:21:32", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T22:54:32", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T08:07:50", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T12:47:09", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T13:23:20", - "normal": 1.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T17:55:40", - "normal": 7.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T19:30:40", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T22:57:00", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T02:25:19", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T16:54:27", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T17:18:04", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T19:15:15", - "normal": 6.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T20:51:16", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T23:10:50", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-29T01:18:06", - "normal": 1.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-29T14:47:42", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-29T16:34:10", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-29T22:26:32", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T04:03:49", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T10:56:21", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T13:27:12", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T19:41:58", - "normal": 2.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T21:08:12", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T22:40:45", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T23:11:40", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-01T11:33:30", - "normal": 2.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-01T20:49:42", - "normal": 5.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-01T23:31:41", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T02:42:26", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T03:08:32", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T12:36:04", - "normal": 7.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T13:23:44", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T20:07:26", - "normal": 7.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T15:01:33", - "normal": 0.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T15:46:39", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T16:41:33", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T17:18:38", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T17:43:38", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T10:16:53", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T14:50:00", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T16:14:19", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T19:21:41", - "normal": 8.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T23:46:41", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T00:44:34", - "expectedNormal": 2, - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T01:02:58", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T12:01:09", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T12:23:18", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T12:51:54", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T15:39:48", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T21:29:36", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-06T04:21:34", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-06T08:53:58", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-07T15:08:48", - "normal": 0.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T19:54:26", - "normal": 7.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-08T15:53:04", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-08T22:22:31", - "normal": 7.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-08T22:47:20", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-09T15:51:36", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T00:59:27", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T10:23:36", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T18:30:44", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T18:39:41", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T19:47:34", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-11T13:53:18", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-11T20:58:05", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T00:35:54", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T13:04:51", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T17:37:35", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T19:09:48", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T19:34:40", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T00:02:43", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T00:11:41", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T08:33:39", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T20:19:52", - "duration": 1800000, - "extended": 2.55, - "normal": 0.6, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-14T16:44:31", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-14T22:46:55", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-15T00:28:57", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-15T08:51:33", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-15T11:33:53", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-15T19:09:51", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-16T17:02:11", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-16T18:49:50", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-16T20:22:02", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-17T11:14:04", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-17T19:29:27", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T06:45:25", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T15:28:35", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T16:20:17", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T16:50:44", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T22:16:57", - "duration": 3600000, - "extended": 4.2, - "normal": 2.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-19T07:18:23", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-19T18:51:48", - "normal": 4.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T08:50:29", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T11:19:38", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T15:42:53", - "duration": 1800000, - "extended": 0.45, - "normal": 1.3, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T17:25:24", - "duration": 3600000, - "extended": 0.75, - "normal": 3, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T21:38:30", - "duration": 3600000, - "extended": 2.85, - "normal": 6.55, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T11:54:08", - "duration": 3600000, - "extended": 2.8, - "normal": 2.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T14:39:04", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T18:23:31", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T19:29:16", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T20:00:12", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T21:40:40", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T23:42:55", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T00:24:30", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T08:20:59", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T21:37:44", - "duration": 3600000, - "extended": 1.2, - "normal": 4.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T22:25:47", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T23:37:05", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T07:32:39", - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T19:09:07", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T20:27:18", - "duration": 3600000, - "extended": 1.75, - "normal": 3.25, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T22:28:35", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T23:23:04", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T08:19:28", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T09:04:06", - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T10:00:56", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T18:30:46", - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T19:44:10", - "normal": 1.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T20:32:30", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T20:39:38", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T09:17:23", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T16:59:11", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T17:49:12", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T19:55:43", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-26T03:01:17", - "normal": 1.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-26T07:05:35", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-26T09:44:50", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-27T16:48:06", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-27T17:13:45", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-27T17:57:18", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-27T22:06:32", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-28T15:46:44", - "normal": 6.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-28T16:18:13", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-28T16:23:18", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-28T16:28:41", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-29T18:27:23", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-30T12:43:51", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-01T17:46:55", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-01T18:30:32", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-01T18:51:38", - "normal": 4.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-02T00:15:19", - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-02T06:49:58", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-02T18:35:00", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T12:03:51", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T12:50:24", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T17:08:12", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T17:41:00", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T19:08:04", - "expectedNormal": 2, - "normal": 0.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T19:08:18", - "normal": 0.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T01:21:22", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T14:10:31", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T17:59:30", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T19:21:37", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T19:25:51", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T20:09:01", - "normal": 7.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T02:02:39", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T02:36:40", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T13:58:30", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T17:17:54", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T23:40:50", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-06T01:28:33", - "normal": 3.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-06T14:59:11", - "normal": 2.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-06T20:26:50", - "duration": 3600000, - "extended": 2, - "normal": 6, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-07T00:48:50", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-07T14:09:43", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-07T16:02:12", - "duration": 5400000, - "extended": 3.25, - "normal": 9.75, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T18:17:26", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T18:29:06", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T20:29:43", - "normal": 5.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T23:53:16", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-09T12:19:24", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-09T16:27:30", - "duration": 3600000, - "extended": 1, - "normal": 5.65, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-09T17:50:34", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-10T00:25:49", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-10T17:43:21", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-10T18:08:03", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-11T13:06:32", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-11T19:37:52", - "normal": 7.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T00:07:01", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T00:42:51", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T07:40:06", - "normal": 3.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T08:50:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T16:09:42", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T21:45:57", - "normal": 6.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T10:56:43", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T11:42:47", - "normal": 1.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T16:33:50", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T18:21:41", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T22:13:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T22:19:30", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T22:48:14", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T23:08:30", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T14:31:41", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T15:53:20", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T17:37:39", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T18:15:11", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T20:29:30", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T12:18:56", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T14:09:52", - "normal": 4.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T17:23:04", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T21:15:01", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T21:44:35", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T22:12:37", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T22:57:20", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T22:58:49", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T09:35:57", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T11:31:07", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T15:12:49", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T15:41:21", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T21:04:38", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-17T03:22:39", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-17T14:09:57", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-17T16:29:43", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T05:26:35", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T08:03:17", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T17:58:39", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T20:40:22", - "duration": 1800000, - "extended": 5.7, - "normal": 1.9, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T08:36:08", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T15:20:39", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T18:22:28", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T18:54:15", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T22:20:06", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T22:47:22", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-20T14:23:03", - "duration": 3600000, - "extended": 1.35, - "normal": 5.4, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-20T15:02:15", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-20T15:50:21", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-21T00:08:35", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-21T12:12:24", - "normal": 5.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-21T15:13:53", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-22T16:11:14", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T01:06:51", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T10:37:02", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T16:18:09", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T16:57:31", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T21:30:01", - "duration": 1800000, - "extended": 3.55, - "normal": 1.15, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T08:03:19", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T13:21:49", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T13:41:26", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T15:13:42", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T17:30:34", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T18:47:01", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-25T00:37:32", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-25T15:27:34", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-25T15:50:46", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-25T18:34:45", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-26T08:00:02", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-26T15:30:21", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-26T16:43:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-26T22:55:06", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-27T00:34:23", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-27T16:08:38", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T10:22:34", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T10:42:12", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T11:14:05", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T12:22:02", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T17:58:24", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T00:59:10", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T13:21:48", - "normal": 3.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T14:26:37", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T15:29:23", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T19:11:00", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T21:59:18", - "duration": 10800000, - "extended": 8.65, - "normal": 2.85, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T07:29:04", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T11:32:41", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T13:33:42", - "normal": 2.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T15:10:57", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T16:48:04", - "duration": 2700000, - "expectedDuration": 3600000, - "expectedExtended": 2.65, - "extended": 1.95, - "normal": 4.5, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T17:35:25", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T06:01:14", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T08:02:24", - "expectedNormal": 1.8, - "normal": 0, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T17:32:27", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T19:24:54", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T20:15:14", - "normal": 7.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T23:11:02", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-01T15:38:03", - "normal": 7.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-02T00:53:24", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-02T09:42:56", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-02T12:33:40", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T13:13:56", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T13:30:33", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T19:02:46", - "normal": 7.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T23:23:36", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T23:30:48", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-04T07:57:10", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-04T17:05:51", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-04T18:14:03", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-05T16:45:27", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-05T19:47:08", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T09:25:42", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T15:20:44", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T16:19:31", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T17:07:49", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T19:58:23", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T14:38:43", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T19:47:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T20:51:30", - "normal": 8.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T21:31:38", - "normal": 5.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T01:05:38", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T10:11:09", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T15:43:17", - "normal": 6.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T19:52:56", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T20:57:40", - "duration": 3600000, - "extended": 2, - "normal": 8.95, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-09T09:07:47", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-09T16:17:45", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-09T17:24:45", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T01:12:55", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T18:24:34", - "normal": 5.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T19:04:48", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T20:30:46", - "normal": 0.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-12T10:04:06", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-13T17:30:51", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-13T18:15:01", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-13T18:43:29", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-14T15:37:44", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T01:47:54", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T13:59:56", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T14:41:43", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T14:44:38", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T21:54:18", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T15:51:57", - "normal": 7.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T16:23:22", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T20:59:44", - "normal": 7.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T22:28:09", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T13:43:39", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T15:22:58", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T20:43:00", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T22:37:07", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T12:51:55", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T15:37:39", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T16:20:47", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T16:23:34", - "expectedNormal": 1, - "normal": 0, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T16:23:47", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T01:18:52", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T18:35:04", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T18:45:16", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T19:19:18", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T19:49:49", - "normal": 9.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-20T13:23:57", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-20T18:56:03", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-21T18:29:04", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-21T20:46:21", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-22T21:10:05", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-22T21:58:04", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-22T22:02:55", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-23T18:27:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-23T20:31:41", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-23T20:59:54", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-23T23:21:11", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-24T10:24:29", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-24T17:07:32", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-24T17:33:08", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-24T18:35:51", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-25T14:07:13", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-25T17:12:17", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-25T21:24:58", - "normal": 8.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T11:35:34", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T11:48:12", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T12:08:19", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T16:13:11", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T22:12:41", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T01:27:13", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T16:56:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T19:56:41", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T20:22:28", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T20:57:07", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T07:42:06", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T09:05:30", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T09:54:05", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T14:01:25", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T15:50:43", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T20:59:49", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T21:29:58", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T01:28:07", - "expectedNormal": 3, - "normal": 0, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T01:28:23", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T05:09:40", - "expectedNormal": 2.55, - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T05:18:26", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T06:58:48", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T07:02:43", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T13:23:14", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T21:18:42", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-30T15:27:04", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-30T15:45:46", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-30T16:03:48", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-30T21:27:24", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-31T00:32:49", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-31T14:12:55", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T00:10:43", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T00:20:00", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T01:11:31", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T18:11:06", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T18:59:49", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T23:21:40", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T01:17:05", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T07:22:03", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T09:19:07", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T15:32:12", - "duration": 3600000, - "extended": 1.65, - "normal": 3.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T17:09:29", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T19:39:58", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T20:38:24", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T20:44:02", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T21:40:20", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T00:20:40", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T06:42:57", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T14:08:27", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T14:48:55", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T17:14:46", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T22:34:31", - "normal": 5.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-04T00:28:34", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-04T06:09:22", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-04T14:45:39", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-04T18:24:53", - "normal": 10.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-05T01:06:54", - "normal": 6.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-05T16:22:33", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-05T16:58:48", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-05T21:45:50", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T00:55:25", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T15:41:42", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T15:45:31", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T16:47:53", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T21:15:40", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-07T19:12:03", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-07T19:57:42", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-07T20:27:57", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-07T23:09:54", - "normal": 10.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T06:49:54", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T13:38:14", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T19:03:48", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T21:12:03", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T22:21:55", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-09T01:19:46", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-09T15:05:45", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-09T22:54:59", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-09T23:26:51", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T16:45:44", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T17:22:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T20:02:24", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T22:48:01", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T23:18:10", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-11T17:11:53", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-11T23:15:24", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-12T00:04:13", - "normal": 2.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-12T00:28:22", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-12T15:21:56", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-13T15:59:02", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-13T22:06:29", - "normal": 6.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-14T11:11:32", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-14T13:09:35", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-14T19:24:39", - "normal": 10.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-15T15:36:19", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-15T21:46:47", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-15T22:10:16", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-16T15:44:33", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-16T21:36:53", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-17T15:59:12", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-17T16:08:56", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-17T21:09:25", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-18T09:37:49", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-18T18:20:54", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-18T18:51:09", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-19T13:27:26", - "duration": 3600000, - "extended": 0.55, - "normal": 0.25, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-19T14:53:40", - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-19T15:24:30", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-20T18:32:41", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-20T21:29:36", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-21T15:35:49", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-21T21:03:52", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-21T22:39:49", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T11:25:56", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T13:19:40", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T17:25:35", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T19:59:31", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T22:50:19", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T11:45:40", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T11:47:49", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T12:07:32", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T15:08:45", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T20:33:01", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T22:00:40", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T06:08:59", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T08:33:59", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T11:22:33", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T21:52:26", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T22:08:46", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-25T16:52:46", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-25T20:23:33", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-25T20:36:44", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T07:18:20", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T10:15:04", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T16:11:43", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T19:25:09", - "normal": 6.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T21:22:26", - "normal": 1.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T12:14:07", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T13:57:02", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T14:09:20", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T15:29:54", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T20:48:41", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T21:12:09", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T21:20:49", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T21:49:25", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T04:50:11", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T07:40:45", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T12:06:19", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T15:46:19", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T21:47:01", - "normal": 12.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T01:12:35", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T02:08:17", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T02:59:26", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T14:42:33", - "normal": 7.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T15:02:43", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T15:12:10", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T19:10:18", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T19:46:49", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T11:29:40", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T13:56:15", - "normal": 5.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T15:42:59", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T22:53:22", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T23:05:22", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T23:35:16", - "normal": 7.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-01T14:27:43", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-01T16:04:42", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-01T22:28:45", - "normal": 6.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-02T17:01:12", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-02T18:18:32", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-02T22:08:17", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-02T22:56:37", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T07:44:00", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T08:42:58", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T15:24:28", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T17:53:59", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T19:00:37", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T22:17:33", - "normal": 7.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-04T09:52:11", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-04T12:55:58", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-04T15:12:11", - "normal": 6.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-04T20:09:22", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-05T03:27:19", - "normal": 4.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-05T19:22:47", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-05T22:39:45", - "normal": 10.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T06:12:37", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T12:42:06", - "normal": 8.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T15:32:00", - "expectedNormal": 4.7, - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T19:07:20", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T19:39:58", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-07T00:20:47", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-07T05:30:49", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-07T08:21:15", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-07T22:44:14", - "normal": 8.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-08T06:58:25", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-08T08:16:59", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-08T13:52:10", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-08T19:52:08", - "normal": 5.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T06:26:22", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T07:43:04", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T15:08:46", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T15:54:44", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T23:03:47", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T23:38:04", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-10T16:02:43", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-10T22:56:35", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-10T23:35:59", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-11T15:03:25", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-11T16:13:04", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-11T21:19:03", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T07:22:58", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T15:16:54", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T15:54:25", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T21:11:04", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T13:15:55", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T13:18:43", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T16:26:19", - "normal": 6.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T20:33:47", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T20:49:06", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T21:24:48", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T23:18:40", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T23:45:17", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T00:25:53", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T01:10:52", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T12:00:00", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T15:36:08", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T16:01:10", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T19:58:59", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T20:51:48", - "normal": 8.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T21:40:26", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T23:14:13", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T00:33:52", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T08:45:17", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T15:49:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T21:53:25", - "normal": 8.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T22:38:18", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-16T16:47:33", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-16T22:22:47", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-16T23:27:48", - "normal": 14.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-17T15:50:12", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-17T15:52:31", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T14:12:19", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T15:09:54", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T15:27:12", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T15:57:46", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T23:28:05", - "normal": 8.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T00:10:14", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T00:46:24", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T01:11:02", - "normal": 5.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T14:59:14", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T16:28:00", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T22:00:22", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T23:24:34", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T17:39:33", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T19:27:43", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T20:07:49", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T20:43:12", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T21:54:33", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-21T14:16:42", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-21T20:42:35", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-22T12:14:12", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T07:12:15", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T11:12:32", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T12:36:16", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T12:50:53", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T14:17:09", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-24T10:47:06", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-24T14:20:06", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-24T16:11:40", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-25T00:18:43", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-25T19:12:42", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-25T20:42:26", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-26T18:49:01", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-27T18:11:11", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-27T20:47:51", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-28T13:28:57", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-28T13:31:35", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-28T13:43:39", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-28T18:08:08", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-29T03:56:45", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-29T15:09:37", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-29T15:58:27", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-30T02:57:09", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-30T16:34:05", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-30T19:17:07", - "expectedNormal": 8, - "normal": 6.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-30T23:28:05", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-31T20:19:12", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-01T16:10:05", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-01T23:01:05", - "normal": 3.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-02T17:16:10", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-02T23:46:20", - "normal": 8.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-03T12:56:37", - "normal": 6.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-03T13:09:30", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-03T16:07:02", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-03T20:10:25", - "duration": 3600000, - "extended": 2.2, - "normal": 12.3, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T05:00:38", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T12:35:17", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T15:46:38", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T22:01:14", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-05T09:37:58", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-05T13:19:18", - "normal": 2, - "subType": "normal", - }, -} - -var PlatformBolusSet = []map[string]interface{}{ - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T05:48:32", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T05:48:32", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T08:48:43", - "normal": 2.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T08:48:43", - "normal": 2.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T17:07:35", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T17:48:17", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-11T22:16:32", - "expectedNormal": 6, - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T02:48:01", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T02:57:56", - "normal": 2.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T02:57:56", - "normal": 2.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T03:45:23", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T04:02:33", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T04:02:33", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T04:07:54", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T12:10:52", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T12:10:52", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T13:43:31", - "normal": 0.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T13:43:31", - "normal": 0.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T18:55:53", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-12T22:06:00", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-13T00:07:54", - "normal": 6.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-13T15:36:15", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-13T15:36:15", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-13T19:15:32", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-13T23:32:46", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-14T02:56:18", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-14T15:05:16", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-14T15:05:16", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-14T18:45:59", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-14T21:06:30", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T02:10:44", - "expectedNormal": 6, - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T10:11:52", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T10:21:08", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T10:52:13", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T18:51:32", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T20:32:07", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T20:43:33", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T20:43:33", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-15T21:26:55", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T07:56:57", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T07:56:57", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T15:32:09", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T15:32:09", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:04:19", - "expectedNormal": 3.7, - "normal": 0.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:04:45", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:23:41", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:35:34", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T16:58:46", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-16T22:04:48", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T07:49:22", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T07:49:22", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T07:58:22", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T08:31:44", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T09:25:59", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T15:19:35", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T15:41:16", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T16:13:32", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T16:51:39", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T17:36:34", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-17T22:24:30", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T00:26:16", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T00:57:05", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T09:39:10", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T13:26:16", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T15:56:31", - "normal": 0.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T15:56:31", - "normal": 0.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T16:46:24", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T17:16:59", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-18T17:16:59", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T01:21:09", - "normal": 2.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T01:21:09", - "normal": 2.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T01:51:44", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T18:01:16", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T19:01:35", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T22:24:42", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T22:27:54", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-19T23:16:39", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T11:50:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T13:36:40", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T13:36:40", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T18:31:12", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T19:04:49", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-20T19:13:53", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-21T14:16:39", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T00:12:03", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T00:12:03", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T13:54:39", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T20:02:33", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T20:09:02", - "normal": 7.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T20:42:46", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-22T20:51:20", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-23T14:51:38", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-23T14:51:38", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-23T17:40:56", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T10:57:40", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T13:49:15", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T13:49:15", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T20:29:08", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T20:29:08", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T23:20:14", - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-24T23:20:14", - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T02:11:25", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T02:11:25", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T03:41:15", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T03:49:26", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T11:34:54", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T11:36:30", - "expectedNormal": 3.7, - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T11:39:54", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T18:55:44", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T21:00:32", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T21:56:23", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-25T22:40:16", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T00:47:19", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T11:19:24", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T11:19:24", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T18:22:46", - "normal": 9.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T18:22:46", - "normal": 9.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T20:06:31", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-26T21:00:39", - "normal": 4.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T00:43:11", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T00:54:23", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T01:21:34", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T01:21:34", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T07:02:47", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T08:20:19", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T08:20:19", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T11:57:25", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T18:36:04", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-27T20:18:11", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T10:55:51", - "normal": 10.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T13:31:27", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T17:47:15", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T18:58:25", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-28T20:20:09", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T05:47:36", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T11:04:51", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T11:17:10", - "expectedNormal": 5, - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T11:17:44", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T11:59:21", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T11:59:21", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T12:33:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T16:04:51", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T18:22:02", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T18:22:02", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-29T20:35:15", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T00:19:10", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T01:14:53", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T11:38:04", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T11:38:04", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T14:10:30", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T18:11:40", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T19:40:37", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-11-30T22:39:58", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T09:55:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T12:02:23", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T12:02:23", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T12:11:07", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T15:03:11", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-01T23:36:08", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-02T13:42:27", - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-02T13:42:27", - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T08:36:32", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T12:46:16", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T14:31:00", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T19:01:03", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T19:13:12", - "duration": 3600000, - "extended": 1.35, - "normal": 3.25, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T19:13:12", - "duration": 3600000, - "extended": 1.35, - "normal": 3.25, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T23:09:17", - "expectedNormal": 5.6, - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-03T23:09:17", - "expectedNormal": 5.6, - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-04T01:32:34", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-04T13:31:48", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-04T23:45:20", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-05T05:38:22", - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-05T05:38:22", - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-05T13:05:36", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-05T18:04:44", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-05T22:31:49", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-06T09:05:49", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-06T19:44:34", - "normal": 3.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-06T19:44:34", - "normal": 3.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-07T11:30:47", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-07T17:39:58", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T09:36:46", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T09:36:46", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T12:09:06", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T13:51:33", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T13:51:33", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T22:47:22", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T23:06:37", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-08T23:34:05", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T11:51:03", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T18:28:48", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T18:41:43", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T19:46:42", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T19:46:42", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-09T22:41:34", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T03:05:28", - "normal": 1.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T03:05:28", - "normal": 1.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T11:34:38", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T14:55:50", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T15:23:08", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T19:28:56", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T21:16:11", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-10T22:17:25", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-11T14:30:42", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-11T19:17:18", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T13:15:43", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T14:37:19", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T20:45:23", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T21:17:50", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T22:07:50", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T23:57:33", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-12T23:57:33", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-13T10:28:04", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-13T10:28:04", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-13T17:42:12", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T04:31:16", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T09:40:01", - "normal": 3.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T09:40:01", - "normal": 3.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T15:57:40", - "normal": 2.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T15:57:40", - "normal": 2.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T17:26:58", - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-14T17:26:58", - "normal": 2.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T05:49:43", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T09:42:54", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T09:42:54", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T15:42:11", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T17:58:05", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T20:36:40", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-15T21:54:57", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T02:10:54", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T05:18:35", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T05:18:35", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T17:03:43", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T21:17:40", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-16T21:27:12", - "expectedNormal": 1.8, - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-17T15:02:37", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-17T15:02:37", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-18T08:53:51", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-18T08:53:51", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-18T14:07:21", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-18T14:07:21", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-19T00:37:12", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-20T22:52:22", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-20T22:52:22", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-21T16:04:44", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-21T16:04:44", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-21T17:31:36", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-22T20:34:13", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T00:32:29", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T00:32:29", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T02:01:53", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T02:01:53", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T13:25:12", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T14:45:29", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T14:45:29", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T15:17:41", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T15:27:27", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T20:51:42", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T20:51:42", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T22:28:05", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-23T22:28:05", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-24T15:45:49", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-24T15:45:49", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-24T17:30:54", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T03:24:31", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T17:51:24", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T18:17:02", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T18:44:42", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-25T19:06:09", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-26T04:38:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-26T21:52:20", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-26T22:10:35", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T00:35:55", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T12:09:08", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T13:12:31", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T22:06:04", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T23:57:59", - "normal": 8.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-27T23:57:59", - "normal": 8.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T13:41:05", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T13:41:05", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T21:53:48", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T21:53:48", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T22:38:58", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-28T23:35:34", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T01:10:10", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T13:28:49", - "normal": 7.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T15:31:09", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T15:47:25", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T20:49:26", - "normal": 10.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T20:49:26", - "normal": 10.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-29T23:31:22", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T01:14:51", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T01:14:51", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T10:07:54", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T14:41:41", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T14:41:41", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T15:36:28", - "normal": 0.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T15:36:28", - "normal": 0.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T17:21:07", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T17:47:07", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T17:47:07", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T19:43:22", - "normal": 10.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T21:42:19", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T23:34:45", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-30T23:57:13", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T14:15:24", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T15:37:20", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T16:37:23", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T20:22:35", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2017-12-31T22:50:28", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T00:18:37", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T03:28:56", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T08:23:20", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T17:09:58", - "normal": 5.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T17:09:58", - "normal": 5.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T20:29:55", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T21:39:29", - "normal": 11.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-01T21:39:29", - "normal": 11.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T01:37:45", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T01:37:45", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T09:05:27", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T09:05:27", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T09:28:02", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T09:28:02", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T15:17:44", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T15:17:44", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T17:05:07", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T21:57:29", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T21:57:29", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T22:31:41", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T23:58:14", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-02T23:58:14", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T06:23:16", - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T06:23:16", - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T13:07:10", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T13:07:10", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T17:36:24", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T17:36:24", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-03T19:19:53", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-04T20:39:32", - "normal": 12.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-04T23:27:30", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-05T11:26:40", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-05T14:39:47", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-05T21:24:08", - "normal": 12.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-05T23:47:57", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-06T10:29:13", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-07T02:43:11", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-07T15:29:23", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-07T15:53:38", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T00:50:58", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T02:22:40", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T10:49:22", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T12:10:15", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T16:06:15", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T21:00:55", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-08T22:52:11", - "normal": 13.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T06:48:05", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T11:57:20", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T14:50:09", - "expectedNormal": 7.1, - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T15:09:57", - "expectedNormal": 5.3, - "normal": 0, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T15:10:07", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T15:45:24", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-09T19:08:06", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T00:20:48", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T09:57:07", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T15:19:38", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T15:19:38", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T19:51:35", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-10T21:04:03", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-11T17:21:27", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-11T23:50:01", - "normal": 9.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-11T23:50:01", - "normal": 9.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-12T14:21:27", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T01:22:50", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T09:16:42", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T09:45:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T17:59:12", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-13T19:51:42", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T01:09:36", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T01:09:36", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T15:27:34", - "normal": 6.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T15:37:30", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T19:52:15", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T22:44:38", - "normal": 11, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-14T23:04:59", - "expectedNormal": 8.7, - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-15T08:08:01", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-15T08:08:01", - "normal": 5.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-15T17:50:26", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-15T18:22:34", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-15T22:12:43", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-16T05:28:57", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-16T19:06:03", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-18T00:44:27", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-18T00:44:27", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-18T15:16:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-18T21:34:19", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-19T15:18:48", - "normal": 7.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-19T15:18:48", - "normal": 7.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-19T18:24:25", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-19T21:40:18", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T01:57:09", - "normal": 5.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T01:57:09", - "normal": 5.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T05:21:15", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T14:43:26", - "normal": 2.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T14:43:26", - "normal": 2.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T20:23:29", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-20T23:15:21", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-21T01:47:25", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-21T01:47:25", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-21T16:32:58", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-21T16:32:58", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-21T21:12:41", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-22T13:07:23", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-22T13:24:37", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-22T13:38:43", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-22T13:38:43", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-22T14:23:46", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T00:01:17", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T02:53:10", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T10:26:09", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T12:45:53", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-23T19:04:33", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T02:03:30", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T02:03:30", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T08:42:05", - "normal": 3.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T08:42:05", - "normal": 3.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T09:11:28", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T13:05:25", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T16:20:41", - "normal": 0.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T16:20:41", - "normal": 0.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T19:39:24", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T22:58:57", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-24T22:58:57", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-25T09:05:32", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-25T09:15:49", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-25T10:05:32", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-25T15:20:46", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-26T00:34:00", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-26T00:40:32", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-26T17:42:21", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-27T00:26:46", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-27T01:56:53", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-27T15:00:57", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-27T16:30:36", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T00:07:24", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T04:04:35", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T11:06:58", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T12:05:56", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T17:32:14", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-28T22:51:31", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-29T09:24:11", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-29T11:48:49", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-01-31T17:35:53", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-01T22:39:45", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-01T23:11:22", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-02T05:32:22", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-02T13:53:59", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-02T15:01:02", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-03T11:47:19", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-03T17:52:13", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-04T00:51:30", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-04T01:35:03", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-04T10:23:28", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-05T00:40:31", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-05T22:10:18", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T00:30:31", - "duration": 9000000, - "extended": 2.4, - "normal": 0.1, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T00:30:31", - "duration": 9000000, - "extended": 2.4, - "normal": 0.1, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T11:27:46", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T12:24:47", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T12:24:47", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T21:00:06", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T21:26:09", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-06T22:30:08", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-07T01:20:24", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-07T01:20:24", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-07T15:08:42", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-07T17:35:21", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-07T17:35:21", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T00:40:52", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T00:40:52", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T04:05:56", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T04:08:07", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T20:24:34", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-08T21:17:19", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-09T03:41:21", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-09T03:43:00", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-09T15:27:27", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-09T15:27:27", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-09T16:50:23", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-10T00:06:05", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-10T07:13:02", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-10T10:23:08", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T01:16:30", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T13:20:10", - "normal": 1.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T13:20:10", - "normal": 1.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T17:04:18", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T19:38:24", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T20:40:19", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T22:22:57", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-11T23:03:25", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T10:31:15", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T10:47:00", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T17:15:24", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T22:52:54", - "duration": 5400000, - "extended": 3.6, - "normal": 0.4, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T22:52:54", - "duration": 5400000, - "extended": 3.6, - "normal": 0.4, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-12T23:37:16", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-13T03:06:20", - "expectedNormal": 2.4, - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-13T04:51:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-13T19:40:33", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-13T20:05:03", - "normal": 0.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-14T17:20:11", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-14T17:56:34", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-15T01:56:38", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-15T17:29:22", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-16T09:23:19", - "normal": 2.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-16T09:23:19", - "normal": 2.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-17T11:56:27", - "normal": 0.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-17T11:56:27", - "normal": 0.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T00:34:51", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T04:32:23", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T12:15:36", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T12:56:37", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-18T20:43:52", - "normal": 9.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T03:06:10", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T17:37:52", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T17:37:52", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T18:33:24", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T22:24:06", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T23:15:16", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-19T23:57:50", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T11:27:44", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T12:13:32", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T17:12:58", - "normal": 7.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T17:12:58", - "normal": 7.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T23:25:38", - "normal": 4.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-20T23:25:38", - "normal": 4.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-21T18:12:48", - "normal": 4.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-21T23:02:43", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-22T05:11:08", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-22T12:46:46", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-22T18:44:55", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-22T23:47:30", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-23T15:22:30", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T01:28:13", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T04:50:59", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T04:50:59", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T10:06:16", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T10:57:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T16:20:38", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T20:57:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-24T21:10:06", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T01:46:05", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T03:01:41", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T03:01:41", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T12:45:34", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T16:35:50", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-25T16:43:09", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-26T14:50:38", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-26T23:18:20", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-27T19:10:37", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-27T19:56:05", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-27T20:05:22", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-02-27T20:33:26", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-01T11:06:45", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-01T13:38:00", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-01T13:38:00", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-01T17:26:06", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T05:10:59", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T14:53:50", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T15:15:41", - "duration": 7200000, - "extended": 4, - "normal": 2.65, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T15:15:41", - "duration": 7200000, - "extended": 4, - "normal": 2.65, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T17:55:24", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T21:27:07", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-02T21:27:07", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-03T02:23:28", - "normal": 3.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-03T02:23:28", - "normal": 3.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-03T07:55:24", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-03T13:31:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-03T17:33:40", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T01:00:34", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T09:51:54", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T13:59:53", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T14:53:15", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T17:26:51", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T19:38:13", - "normal": 8.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T23:09:52", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T23:57:26", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-04T23:57:26", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-05T03:09:50", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-05T14:54:46", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-05T18:29:31", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-06T00:34:35", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-06T01:21:36", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-06T06:12:45", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-06T19:38:19", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T08:26:18", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T10:24:27", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T16:59:43", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T22:10:21", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-07T23:47:40", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-08T00:47:32", - "duration": 10800000, - "extended": 1.65, - "subType": "square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-08T00:47:32", - "duration": 10800000, - "extended": 1.65, - "subType": "square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-08T17:20:24", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-08T23:16:45", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-08T23:16:45", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-09T09:43:12", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-09T19:36:18", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-09T21:47:07", - "normal": 11, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-09T22:28:29", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T00:56:27", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T05:18:33", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T10:09:03", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T19:08:41", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T19:30:42", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T21:00:08", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-10T21:11:26", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T00:12:25", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T00:12:25", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T03:50:32", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T09:48:55", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T17:56:25", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T21:45:42", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T23:48:21", - "normal": 7.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-11T23:59:24", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-12T11:02:19", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-12T14:13:44", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-12T23:30:03", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-13T00:01:21", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-13T08:23:02", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-13T15:29:58", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-13T16:25:10", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T01:00:14", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T01:48:33", - "duration": 7200000, - "extended": 5, - "subType": "square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T08:26:33", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T09:15:40", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T21:17:36", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-14T21:36:42", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T01:00:44", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T12:10:00", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T13:36:53", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T21:24:43", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-15T22:46:02", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-16T19:49:33", - "normal": 12.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-16T19:49:33", - "normal": 12.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-17T15:56:01", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-17T15:56:01", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-18T10:02:04", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-18T15:29:15", - "normal": 6.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-18T15:29:15", - "normal": 6.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-18T16:27:25", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-18T21:15:02", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-19T06:28:44", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-19T15:28:25", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-19T22:15:08", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T08:14:49", - "duration": 3600000, - "extended": 1.5, - "normal": 0.5, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T12:02:19", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T13:19:06", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T16:07:19", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T19:43:27", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-20T20:56:53", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-21T00:32:48", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-21T14:39:05", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-21T21:09:21", - "normal": 12, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-21T22:14:04", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T03:19:52", - "expectedNormal": 5.15, - "normal": 0.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T03:19:52", - "expectedNormal": 5.15, - "normal": 0.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T03:20:35", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T10:57:48", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T16:15:49", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-22T23:32:14", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T03:44:48", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T10:03:49", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T12:03:21", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T12:03:21", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T12:08:31", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T17:28:19", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T18:10:06", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T22:45:10", - "normal": 6.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-23T23:57:11", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T01:52:51", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T04:04:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T10:09:10", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T15:22:15", - "normal": 9.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T15:59:21", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-24T18:45:12", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T03:44:15", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T04:12:56", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T13:25:50", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T15:47:08", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T16:27:53", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T16:27:53", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-25T17:26:51", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T01:03:51", - "normal": 9.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T01:03:51", - "normal": 9.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T04:48:39", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T15:52:08", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T18:11:28", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T21:42:00", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-26T23:21:43", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-27T13:11:38", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-27T13:27:58", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-27T13:43:12", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-27T14:19:41", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-28T01:21:26", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-28T02:49:55", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-28T02:49:55", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-28T12:09:39", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-28T21:12:56", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T01:42:57", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T12:10:07", - "normal": 8.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T12:10:07", - "normal": 8.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T20:29:43", - "normal": 8.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T20:29:43", - "normal": 8.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T23:08:20", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T23:23:56", - "expectedNormal": 2, - "normal": 0.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T23:24:13", - "expectedNormal": 3.8, - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-29T23:25:03", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-30T09:17:33", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-30T11:41:40", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-30T18:46:16", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-30T22:26:35", - "normal": 7.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-30T22:26:35", - "normal": 7.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-31T09:34:04", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-31T11:02:09", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-03-31T18:03:31", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-01T13:35:12", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-01T19:00:43", - "expectedNormal": 5.5, - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-02T11:24:01", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-02T11:24:01", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T00:24:02", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T00:24:02", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T04:46:03", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T13:58:14", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T15:41:52", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T22:48:16", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T22:48:16", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T22:53:19", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-03T23:37:06", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T17:49:44", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T18:25:58", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T20:06:51", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T20:50:31", - "expectedNormal": 6.5, - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-04T21:47:42", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T11:10:22", - "normal": 8.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T13:57:52", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T14:41:02", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T19:55:35", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T20:07:23", - "normal": 6.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T20:07:23", - "normal": 6.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T23:10:52", - "normal": 10.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-05T23:10:52", - "normal": 10.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-06T17:04:13", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T00:30:35", - "normal": 13, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T11:30:23", - "expectedNormal": 11.3, - "normal": 7.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T11:30:23", - "expectedNormal": 11.3, - "normal": 7.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T13:39:36", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T15:31:20", - "normal": 7.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T17:03:27", - "normal": 6.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T19:36:38", - "normal": 11.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-07T19:36:38", - "normal": 11.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T02:04:38", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T02:04:38", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T11:36:22", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T11:36:22", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T15:35:43", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T16:36:54", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T17:06:19", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T17:06:19", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T18:36:43", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T20:45:53", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T21:43:56", - "normal": 5.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T22:27:26", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-08T22:27:26", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-09T13:34:32", - "normal": 4.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-09T13:34:32", - "normal": 4.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-09T23:51:42", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T11:33:52", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T15:06:31", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T16:39:01", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T23:28:10", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T23:28:10", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T23:56:06", - "normal": 3.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-10T23:56:06", - "normal": 3.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-11T08:31:34", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-11T14:14:04", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-11T21:33:10", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-11T21:33:10", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-12T13:11:06", - "normal": 5.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-12T15:22:32", - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-12T15:22:32", - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-12T20:37:48", - "duration": 3600000, - "extended": 1.4, - "normal": 4.1, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-12T20:37:48", - "duration": 3600000, - "extended": 1.4, - "normal": 4.1, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T07:00:52", - "normal": 2.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T07:00:52", - "normal": 2.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T11:55:34", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T15:38:33", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T15:38:33", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T16:43:21", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T22:25:40", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T23:43:31", - "duration": 3600000, - "extended": 3, - "normal": 4.5, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-13T23:43:31", - "duration": 3600000, - "extended": 3, - "normal": 4.5, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T07:24:30", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T11:26:07", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T14:02:33", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T16:13:29", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-14T16:21:37", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-15T04:30:42", - "normal": 2.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-15T04:30:42", - "normal": 2.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-15T11:27:28", - "normal": 9.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-15T21:09:40", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-15T21:29:47", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T08:42:28", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T08:42:28", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T09:08:02", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T18:50:11", - "normal": 7.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T18:50:11", - "normal": 7.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T22:19:29", - "normal": 8.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-16T22:19:29", - "normal": 8.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T07:49:58", - "expectedNormal": 6.25, - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T07:49:58", - "expectedNormal": 6.25, - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T10:22:10", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T15:38:57", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T16:53:15", - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T16:53:15", - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T23:01:44", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T23:01:44", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-17T23:17:46", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-18T03:36:54", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-18T08:15:40", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-18T13:03:08", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-18T13:03:08", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-18T22:49:11", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-19T10:49:57", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-19T10:49:57", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-19T12:47:07", - "normal": 7.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-19T12:47:07", - "normal": 7.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-19T18:51:49", - "normal": 0.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-19T18:51:49", - "normal": 0.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T00:34:12", - "normal": 4.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T00:34:12", - "normal": 4.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T11:55:56", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T11:55:56", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T12:21:25", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T12:25:59", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T12:40:44", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T16:51:52", - "normal": 5.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T16:51:52", - "normal": 5.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T17:13:53", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T18:53:57", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T21:13:02", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T21:17:28", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-20T22:56:20", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T05:00:30", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T05:00:30", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T14:57:12", - "expectedNormal": 5.7, - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T17:25:57", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T19:55:14", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T20:21:02", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T20:48:12", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-21T23:36:01", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T00:17:02", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T07:20:00", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T07:20:00", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T09:32:51", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T15:34:54", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T17:17:07", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T18:33:33", - "normal": 8.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T19:56:36", - "normal": 4.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-22T21:38:22", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T14:44:27", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T16:39:55", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T17:17:36", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T18:45:04", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T21:54:57", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T23:08:34", - "expectedNormal": 2.5, - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-23T23:30:54", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T10:55:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T16:10:07", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T16:10:07", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T18:45:06", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T18:45:06", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-24T21:29:29", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-25T02:05:38", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-25T16:31:35", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-25T16:52:59", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-25T23:23:29", - "normal": 9.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-25T23:23:29", - "normal": 9.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T10:15:03", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T13:15:18", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T13:53:04", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T15:43:54", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-26T20:06:36", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-27T12:42:46", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-27T15:48:19", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-27T15:53:18", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-27T23:14:39", - "normal": 9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T02:49:38", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T14:15:39", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T14:15:39", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T15:36:19", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T17:22:40", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-28T23:33:46", - "normal": 6.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-29T12:43:56", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-29T14:24:57", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-29T16:00:35", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-29T16:00:35", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-29T22:51:00", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-30T16:41:59", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-30T23:51:20", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-04-30T23:51:20", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-01T00:40:06", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-01T02:19:29", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-01T15:47:28", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-01T17:58:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-01T17:58:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T01:01:32", - "duration": 5400000, - "extended": 1.85, - "normal": 0.05, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T01:01:32", - "duration": 5400000, - "extended": 1.85, - "normal": 0.05, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T14:35:54", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T16:30:55", - "normal": 1.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T16:30:55", - "normal": 1.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T18:03:13", - "normal": 2.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T18:03:13", - "normal": 2.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T18:30:32", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-02T22:44:03", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-03T13:28:40", - "normal": 7.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-03T13:28:40", - "normal": 7.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-03T22:38:40", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-03T22:38:40", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T06:40:11", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T12:09:02", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T12:42:38", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T13:58:04", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T19:31:20", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-04T19:31:20", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-05T13:12:58", - "normal": 5.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-05T13:12:58", - "normal": 5.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-05T17:02:00", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-05T17:02:00", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-05T22:18:24", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-05T22:18:24", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-06T12:34:16", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-06T20:28:21", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-06T21:05:28", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-07T10:11:40", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-07T12:47:09", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-07T12:47:09", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-07T20:59:51", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-07T21:46:06", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-08T07:29:03", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-08T07:29:03", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-08T13:44:00", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-08T13:44:00", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-08T20:00:38", - "normal": 2.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-08T20:00:38", - "normal": 2.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-09T14:28:06", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-09T14:28:06", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-09T23:50:14", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T10:13:12", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T12:28:54", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T12:28:54", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T14:38:18", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T18:48:40", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T18:48:40", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T19:22:11", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T20:10:02", - "normal": 0.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T20:10:02", - "normal": 0.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-10T20:43:41", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T02:11:06", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T15:22:52", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T19:51:32", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T20:01:17", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T21:07:27", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-11T22:40:53", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T00:51:28", - "normal": 5.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T00:51:28", - "normal": 5.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T09:31:50", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T17:24:32", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T17:31:58", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T19:20:54", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T20:09:19", - "normal": 6.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-12T23:53:39", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T06:04:08", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T09:33:30", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T09:33:30", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T10:02:35", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T13:25:22", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T14:39:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T21:27:31", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T21:49:54", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-13T21:49:54", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-14T06:30:45", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-14T17:13:50", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-14T17:13:50", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-14T19:51:30", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T02:59:12", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T18:34:17", - "normal": 8.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T18:34:17", - "normal": 8.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T20:03:48", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T20:13:10", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T21:08:56", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-15T21:38:31", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T11:44:10", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T13:54:41", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T17:33:07", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T18:59:52", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T22:40:06", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-16T22:40:06", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T10:47:43", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T17:33:07", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T17:33:07", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T21:09:30", - "normal": 8.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T21:09:30", - "normal": 8.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T21:38:23", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-17T21:38:23", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-18T14:40:29", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-18T16:20:15", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-18T17:18:29", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-18T21:04:49", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-18T21:04:49", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T08:29:53", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T08:29:53", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T10:55:07", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T13:03:51", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T20:15:44", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T20:28:37", - "normal": 10.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-19T20:28:37", - "normal": 10.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T00:18:39", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T01:24:17", - "normal": 0.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T01:24:17", - "normal": 0.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T07:49:45", - "normal": 0.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T07:49:45", - "normal": 0.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T11:51:55", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T12:13:22", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T14:57:44", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-20T18:03:00", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T10:31:41", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T10:31:41", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T13:57:19", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T19:23:59", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T19:23:59", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-21T22:46:23", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-22T09:51:09", - "normal": 9.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-22T09:51:09", - "normal": 9.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-22T19:41:23", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-22T19:41:23", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-22T22:49:19", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T07:43:22", - "normal": 5.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T07:43:22", - "normal": 5.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T15:05:51", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T15:05:51", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T16:43:30", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T16:43:30", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T20:24:21", - "normal": 10.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T20:24:21", - "normal": 10.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-23T20:36:41", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T01:31:04", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T01:31:04", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T12:17:15", - "normal": 4.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T12:17:15", - "normal": 4.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T13:52:54", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T22:00:26", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T22:31:42", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-24T22:31:42", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T07:08:36", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T07:08:36", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T09:25:26", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T09:25:26", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T10:43:07", - "duration": 3600000, - "extended": 2.15, - "normal": 6.35, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T10:43:07", - "duration": 3600000, - "extended": 2.15, - "normal": 6.35, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T15:29:54", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T19:28:58", - "normal": 4.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-25T21:48:56", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T07:47:05", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T15:09:57", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T15:23:19", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T19:21:32", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T19:21:32", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-26T22:54:32", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T08:07:50", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T08:07:50", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T12:47:09", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T12:47:09", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T13:23:20", - "normal": 1.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T13:23:20", - "normal": 1.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T17:55:40", - "normal": 7.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T19:30:40", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-27T22:57:00", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T02:25:19", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T16:54:27", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T16:54:27", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T17:18:04", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T19:15:15", - "normal": 6.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T20:51:16", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-28T23:10:50", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-29T01:18:06", - "normal": 1.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-29T01:18:06", - "normal": 1.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-29T14:47:42", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-29T16:34:10", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-29T22:26:32", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T04:03:49", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T10:56:21", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T13:27:12", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T19:41:58", - "normal": 2.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T19:41:58", - "normal": 2.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T21:08:12", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T21:08:12", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T22:40:45", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-05-31T23:11:40", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-01T11:33:30", - "normal": 2.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-01T11:33:30", - "normal": 2.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-01T20:49:42", - "normal": 5.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-01T20:49:42", - "normal": 5.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-01T23:31:41", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T02:42:26", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T02:42:26", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T03:08:32", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T12:36:04", - "normal": 7.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T12:36:04", - "normal": 7.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T13:23:44", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-02T20:07:26", - "normal": 7.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T15:01:33", - "normal": 0.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T15:46:39", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T16:41:33", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T17:18:38", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-03T17:43:38", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T10:16:53", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T14:50:00", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T16:14:19", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T19:21:41", - "normal": 8.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T19:21:41", - "normal": 8.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-04T23:46:41", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T00:44:34", - "expectedNormal": 2, - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T01:02:58", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T12:01:09", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T12:01:09", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T12:23:18", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T12:51:54", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T15:39:48", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T15:39:48", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T21:29:36", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-05T21:29:36", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-06T04:21:34", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-06T04:21:34", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-06T08:53:58", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-06T08:53:58", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-07T15:08:48", - "normal": 0.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T19:54:26", - "normal": 7.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-08T15:53:04", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-08T15:53:04", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-08T22:22:31", - "normal": 7.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-08T22:47:20", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-09T15:51:36", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T00:59:27", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T00:59:27", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T10:23:36", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T18:30:44", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T18:39:41", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T18:39:41", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-10T19:47:34", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-11T13:53:18", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-11T20:58:05", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T00:35:54", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T13:04:51", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T17:37:35", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T19:09:48", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T19:09:48", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-12T19:34:40", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T00:02:43", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T00:11:41", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T00:11:41", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T08:33:39", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T20:19:52", - "duration": 1800000, - "extended": 2.55, - "normal": 0.6, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-13T20:19:52", - "duration": 1800000, - "extended": 2.55, - "normal": 0.6, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-14T16:44:31", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-14T16:44:31", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-14T22:46:55", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-15T00:28:57", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-15T08:51:33", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-15T11:33:53", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-15T19:09:51", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-16T17:02:11", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-16T17:02:11", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-16T18:49:50", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-16T20:22:02", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-17T11:14:04", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-17T19:29:27", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T06:45:25", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T15:28:35", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T16:20:17", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T16:50:44", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T22:16:57", - "duration": 3600000, - "extended": 4.2, - "normal": 2.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-18T22:16:57", - "duration": 3600000, - "extended": 4.2, - "normal": 2.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-19T07:18:23", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-19T18:51:48", - "normal": 4.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-19T18:51:48", - "normal": 4.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T08:50:29", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T11:19:38", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T11:19:38", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T15:42:53", - "duration": 1800000, - "extended": 0.45, - "normal": 1.3, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T15:42:53", - "duration": 1800000, - "extended": 0.45, - "normal": 1.3, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T17:25:24", - "duration": 3600000, - "extended": 0.75, - "normal": 3, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T17:25:24", - "duration": 3600000, - "extended": 0.75, - "normal": 3, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T21:38:30", - "duration": 3600000, - "extended": 2.85, - "normal": 6.55, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-20T21:38:30", - "duration": 3600000, - "extended": 2.85, - "normal": 6.55, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T11:54:08", - "duration": 3600000, - "extended": 2.8, - "normal": 2.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T14:39:04", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T14:39:04", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T18:23:31", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T19:29:16", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T20:00:12", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T20:00:12", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T21:40:40", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-21T23:42:55", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T00:24:30", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T08:20:59", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T08:20:59", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T21:37:44", - "duration": 3600000, - "extended": 1.2, - "normal": 4.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T21:37:44", - "duration": 3600000, - "extended": 1.2, - "normal": 4.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T22:25:47", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T23:37:05", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-22T23:37:05", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T07:32:39", - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T07:32:39", - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T19:09:07", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T20:27:18", - "duration": 3600000, - "extended": 1.75, - "normal": 3.25, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T22:28:35", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-23T23:23:04", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T08:19:28", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T08:19:28", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T09:04:06", - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T09:04:06", - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T10:00:56", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T10:00:56", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T18:30:46", - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T18:30:46", - "normal": 4.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T19:44:10", - "normal": 1.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T19:44:10", - "normal": 1.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T20:32:30", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T20:39:38", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-24T20:39:38", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T09:17:23", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T16:59:11", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T16:59:11", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T17:49:12", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T19:55:43", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-25T19:55:43", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-26T03:01:17", - "normal": 1.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-26T03:01:17", - "normal": 1.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-26T07:05:35", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-26T09:44:50", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-26T09:44:50", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-27T16:48:06", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-27T17:13:45", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-27T17:57:18", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-27T22:06:32", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-27T22:06:32", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-28T15:46:44", - "normal": 6.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-28T15:46:44", - "normal": 6.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-28T16:18:13", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-28T16:23:18", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-28T16:28:41", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-29T18:27:23", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-29T18:27:23", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-30T12:43:51", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-06-30T12:43:51", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-01T17:46:55", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-01T17:46:55", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-01T18:30:32", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-01T18:51:38", - "normal": 4.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-01T18:51:38", - "normal": 4.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-02T00:15:19", - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-02T00:15:19", - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-02T06:49:58", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-02T06:49:58", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-02T18:35:00", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-02T18:35:00", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T12:03:51", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T12:50:24", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T17:08:12", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T17:41:00", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T17:41:00", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T19:08:04", - "expectedNormal": 2, - "normal": 0.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-03T19:08:18", - "normal": 0.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T01:21:22", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T14:10:31", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T14:10:31", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T17:59:30", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T17:59:30", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T19:21:37", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T19:21:37", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T19:25:51", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T20:09:01", - "normal": 7.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-04T20:09:01", - "normal": 7.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T02:02:39", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T02:02:39", - "normal": 1.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T02:36:40", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T13:58:30", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T13:58:30", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T17:17:54", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T17:17:54", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T23:40:50", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-05T23:40:50", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-06T01:28:33", - "normal": 3.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-06T01:28:33", - "normal": 3.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-06T14:59:11", - "normal": 2.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-06T14:59:11", - "normal": 2.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-06T20:26:50", - "duration": 3600000, - "extended": 2, - "normal": 6, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-06T20:26:50", - "duration": 3600000, - "extended": 2, - "normal": 6, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-07T00:48:50", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-07T14:09:43", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-07T16:02:12", - "duration": 5400000, - "extended": 3.25, - "normal": 9.75, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T18:17:26", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T18:29:06", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T20:29:43", - "normal": 5.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T20:29:43", - "normal": 5.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T23:53:16", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-08T23:53:16", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-09T12:19:24", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-09T12:19:24", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-09T16:27:30", - "duration": 3600000, - "extended": 1, - "normal": 5.65, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-09T16:27:30", - "duration": 3600000, - "extended": 1, - "normal": 5.65, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-09T17:50:34", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-10T00:25:49", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-10T17:43:21", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-10T18:08:03", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-11T13:06:32", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-11T19:37:52", - "normal": 7.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-11T19:37:52", - "normal": 7.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T00:07:01", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T00:07:01", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T00:42:51", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T07:40:06", - "normal": 3.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T07:40:06", - "normal": 3.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T08:50:10", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T16:09:42", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T21:45:57", - "normal": 6.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-12T21:45:57", - "normal": 6.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T10:56:43", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T11:42:47", - "normal": 1.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T11:42:47", - "normal": 1.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T16:33:50", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T18:21:41", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T22:13:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T22:19:30", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T22:48:14", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-13T23:08:30", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T14:31:41", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T15:53:20", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T17:37:39", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T18:15:11", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-14T20:29:30", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T12:18:56", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T14:09:52", - "normal": 4.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T14:09:52", - "normal": 4.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T17:23:04", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T17:23:04", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T21:15:01", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T21:44:35", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T22:12:37", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T22:57:20", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-15T22:58:49", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T09:35:57", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T11:31:07", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T15:12:49", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T15:41:21", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-16T21:04:38", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-17T03:22:39", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-17T03:22:39", - "normal": 1.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-17T14:09:57", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-17T16:29:43", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-17T16:29:43", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T05:26:35", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T05:26:35", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T08:03:17", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T17:58:39", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T20:40:22", - "duration": 1800000, - "extended": 5.7, - "normal": 1.9, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-18T20:40:22", - "duration": 1800000, - "extended": 5.7, - "normal": 1.9, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T08:36:08", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T15:20:39", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T18:22:28", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T18:54:15", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T22:20:06", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-19T22:47:22", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-20T14:23:03", - "duration": 3600000, - "extended": 1.35, - "normal": 5.4, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-20T14:23:03", - "duration": 3600000, - "extended": 1.35, - "normal": 5.4, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-20T15:02:15", - "normal": 3.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-20T15:50:21", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-21T00:08:35", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-21T00:08:35", - "normal": 1.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-21T12:12:24", - "normal": 5.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-21T12:12:24", - "normal": 5.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-21T15:13:53", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-21T15:13:53", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-22T16:11:14", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T01:06:51", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T01:06:51", - "normal": 2.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T10:37:02", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T16:18:09", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T16:18:09", - "normal": 6.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T16:57:31", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T21:30:01", - "duration": 1800000, - "extended": 3.55, - "normal": 1.15, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-23T21:30:01", - "duration": 1800000, - "extended": 3.55, - "normal": 1.15, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T08:03:19", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T13:21:49", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T13:41:26", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T15:13:42", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T17:30:34", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-24T18:47:01", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-25T00:37:32", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-25T15:27:34", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-25T15:50:46", - "normal": 6.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-25T18:34:45", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-25T18:34:45", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-26T08:00:02", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-26T15:30:21", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-26T15:30:21", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-26T16:43:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-26T22:55:06", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-27T00:34:23", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-27T16:08:38", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T10:22:34", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T10:42:12", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T11:14:05", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T12:22:02", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T12:22:02", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-28T17:58:24", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T00:59:10", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T13:21:48", - "normal": 3.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T13:21:48", - "normal": 3.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T14:26:37", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T14:26:37", - "normal": 5.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T15:29:23", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T19:11:00", - "normal": 3.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T21:59:18", - "duration": 10800000, - "extended": 8.65, - "normal": 2.85, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-29T21:59:18", - "duration": 10800000, - "extended": 8.65, - "normal": 2.85, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T07:29:04", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T11:32:41", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T11:32:41", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T13:33:42", - "normal": 2.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T13:33:42", - "normal": 2.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T15:10:57", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T16:48:04", - "duration": 2700000, - "expectedDuration": 3600000, - "expectedExtended": 2.65, - "extended": 1.95, - "normal": 4.5, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T16:48:04", - "duration": 2700000, - "expectedDuration": 3600000, - "expectedExtended": 2.65, - "extended": 1.95, - "normal": 4.5, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-30T17:35:25", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T06:01:14", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T08:02:24", - "expectedNormal": 1.8, - "normal": 0, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T17:32:27", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T17:32:27", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T19:24:54", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T20:15:14", - "normal": 7.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T20:15:14", - "normal": 7.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-07-31T23:11:02", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-01T15:38:03", - "normal": 7.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-02T00:53:24", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-02T00:53:24", - "normal": 1.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-02T09:42:56", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-02T12:33:40", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T13:13:56", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T13:13:56", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T13:30:33", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T19:02:46", - "normal": 7.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T19:02:46", - "normal": 7.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T23:23:36", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-03T23:30:48", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-04T07:57:10", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-04T17:05:51", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-04T18:14:03", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-05T16:45:27", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-05T19:47:08", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T09:25:42", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T15:20:44", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T16:19:31", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T17:07:49", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T19:58:23", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-06T19:58:23", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T14:38:43", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T19:47:20", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T20:51:30", - "normal": 8.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T20:51:30", - "normal": 8.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T21:31:38", - "normal": 5.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-07T21:31:38", - "normal": 5.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T01:05:38", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T10:11:09", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T15:43:17", - "normal": 6.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T15:43:17", - "normal": 6.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T19:52:56", - "normal": 0.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T20:57:40", - "duration": 3600000, - "extended": 2, - "normal": 8.95, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-08T20:57:40", - "duration": 3600000, - "extended": 2, - "normal": 8.95, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-09T09:07:47", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-09T16:17:45", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-09T17:24:45", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T01:12:55", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T18:24:34", - "normal": 5.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T18:24:34", - "normal": 5.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T19:04:48", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T20:30:46", - "normal": 0.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-11T20:30:46", - "normal": 0.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-12T10:04:06", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-13T17:30:51", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-13T18:15:01", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-13T18:15:01", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-13T18:43:29", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-14T15:37:44", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T01:47:54", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T13:59:56", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T14:41:43", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T14:44:38", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-15T21:54:18", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T15:51:57", - "normal": 7.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T15:51:57", - "normal": 7.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T16:23:22", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T20:59:44", - "normal": 7.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T20:59:44", - "normal": 7.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-16T22:28:09", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T13:43:39", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T15:22:58", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T20:43:00", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T20:43:00", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T22:37:07", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-17T22:37:07", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T12:51:55", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T15:37:39", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T15:37:39", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T16:20:47", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T16:23:34", - "expectedNormal": 1, - "normal": 0, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-18T16:23:47", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T01:18:52", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T18:35:04", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T18:35:04", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T18:45:16", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T19:19:18", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-19T19:49:49", - "normal": 9.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-20T13:23:57", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-20T13:23:57", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-20T18:56:03", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-20T18:56:03", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-21T18:29:04", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-21T18:29:04", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-21T20:46:21", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-21T20:46:21", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-22T21:10:05", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-22T21:58:04", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-22T22:02:55", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-23T18:27:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-23T18:27:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-23T20:31:41", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-23T20:59:54", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-23T23:21:11", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-24T10:24:29", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-24T17:07:32", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-24T17:33:08", - "normal": 0.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-24T18:35:51", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-25T14:07:13", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-25T17:12:17", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-25T21:24:58", - "normal": 8.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T11:35:34", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T11:48:12", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T12:08:19", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T16:13:11", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-26T22:12:41", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T01:27:13", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T16:56:37", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T19:56:41", - "normal": 1.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T20:22:28", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-27T20:57:07", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T07:42:06", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T07:42:06", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T09:05:30", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T09:05:30", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T09:54:05", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T09:54:05", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T14:01:25", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T15:50:43", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T20:59:49", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-28T21:29:58", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T01:28:07", - "expectedNormal": 3, - "normal": 0, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T01:28:23", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T05:09:40", - "expectedNormal": 2.55, - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T05:09:40", - "expectedNormal": 2.55, - "normal": 1.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T05:18:26", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T05:18:26", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T06:58:48", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T07:02:43", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T13:23:14", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T21:18:42", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-29T21:18:42", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-30T15:27:04", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-30T15:45:46", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-30T16:03:48", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-30T21:27:24", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-31T00:32:49", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-31T00:32:49", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-08-31T14:12:55", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T00:10:43", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T00:20:00", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T01:11:31", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T18:11:06", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T18:59:49", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T18:59:49", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-01T23:21:40", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T01:17:05", - "normal": 2.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T07:22:03", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T09:19:07", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T15:32:12", - "duration": 3600000, - "extended": 1.65, - "normal": 3.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T15:32:12", - "duration": 3600000, - "extended": 1.65, - "normal": 3.8, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T17:09:29", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T19:39:58", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T19:39:58", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T20:38:24", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T20:38:24", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T20:44:02", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-02T21:40:20", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T00:20:40", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T00:20:40", - "normal": 3.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T06:42:57", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T14:08:27", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T14:48:55", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T17:14:46", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-03T22:34:31", - "normal": 5.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-04T00:28:34", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-04T06:09:22", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-04T14:45:39", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-04T18:24:53", - "normal": 10.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-05T01:06:54", - "normal": 6.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-05T16:22:33", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-05T16:58:48", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-05T21:45:50", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T00:55:25", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T15:41:42", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T15:45:31", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T16:47:53", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T21:15:40", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-06T21:15:40", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-07T19:12:03", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-07T19:57:42", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-07T20:27:57", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-07T23:09:54", - "normal": 10.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T06:49:54", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T13:38:14", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T19:03:48", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T21:12:03", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-08T22:21:55", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-09T01:19:46", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-09T15:05:45", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-09T22:54:59", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-09T23:26:51", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T16:45:44", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T17:22:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T20:02:24", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T22:48:01", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-10T23:18:10", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-11T17:11:53", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-11T23:15:24", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-12T00:04:13", - "normal": 2.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-12T00:04:13", - "normal": 2.25, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-12T00:28:22", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-12T15:21:56", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-13T15:59:02", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-13T22:06:29", - "normal": 6.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-14T11:11:32", - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-14T13:09:35", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-14T19:24:39", - "normal": 10.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-14T19:24:39", - "normal": 10.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-15T15:36:19", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-15T21:46:47", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-15T21:46:47", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-15T22:10:16", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-16T15:44:33", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-16T21:36:53", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-17T15:59:12", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-17T16:08:56", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-17T21:09:25", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-17T21:09:25", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-18T09:37:49", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-18T18:20:54", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-18T18:51:09", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-19T13:27:26", - "duration": 3600000, - "extended": 0.55, - "normal": 0.25, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-19T13:27:26", - "duration": 3600000, - "extended": 0.55, - "normal": 0.25, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-19T14:53:40", - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-19T14:53:40", - "normal": 4.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-19T15:24:30", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-20T18:32:41", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-20T21:29:36", - "normal": 5.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-21T15:35:49", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-21T15:35:49", - "normal": 5.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-21T21:03:52", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-21T22:39:49", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T11:25:56", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T13:19:40", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T17:25:35", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T19:59:31", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-22T22:50:19", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T11:45:40", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T11:47:49", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T12:07:32", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T15:08:45", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T20:33:01", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-23T22:00:40", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T06:08:59", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T08:33:59", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T11:22:33", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T21:52:26", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-24T22:08:46", - "normal": 7.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-25T16:52:46", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-25T20:23:33", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-25T20:36:44", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T07:18:20", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T10:15:04", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T16:11:43", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T19:25:09", - "normal": 6.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T21:22:26", - "normal": 1.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-26T21:22:26", - "normal": 1.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T12:14:07", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T13:57:02", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T14:09:20", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T15:29:54", - "normal": 2.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T20:48:41", - "normal": 2.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T21:12:09", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T21:20:49", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-27T21:49:25", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T04:50:11", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T07:40:45", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T12:06:19", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T15:46:19", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T15:46:19", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T21:47:01", - "normal": 12.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-28T21:47:01", - "normal": 12.35, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T01:12:35", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T02:08:17", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T02:59:26", - "normal": 0.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T14:42:33", - "normal": 7.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T14:42:33", - "normal": 7.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T15:02:43", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T15:12:10", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T19:10:18", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-29T19:46:49", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T11:29:40", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T13:56:15", - "normal": 5.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T15:42:59", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T22:53:22", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T23:05:22", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-09-30T23:35:16", - "normal": 7.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-01T14:27:43", - "normal": 1.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-01T16:04:42", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-01T22:28:45", - "normal": 6.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-01T22:28:45", - "normal": 6.85, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-02T17:01:12", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-02T17:01:12", - "normal": 0.7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-02T18:18:32", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-02T22:08:17", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-02T22:56:37", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T07:44:00", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T08:42:58", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T15:24:28", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T15:24:28", - "normal": 3.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T17:53:59", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T17:53:59", - "normal": 0.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T19:00:37", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T22:17:33", - "normal": 7.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-03T22:17:33", - "normal": 7.65, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-04T09:52:11", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-04T12:55:58", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-04T12:55:58", - "normal": 2.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-04T15:12:11", - "normal": 6.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-04T20:09:22", - "normal": 3.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-05T03:27:19", - "normal": 4.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-05T03:27:19", - "normal": 4.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-05T19:22:47", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-05T19:22:47", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-05T22:39:45", - "normal": 10.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-05T22:39:45", - "normal": 10.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T06:12:37", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T06:12:37", - "normal": 4.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T12:42:06", - "normal": 8.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T15:32:00", - "expectedNormal": 4.7, - "normal": 2.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T19:07:20", - "normal": 4.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-06T19:39:58", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-07T00:20:47", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-07T05:30:49", - "normal": 2.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-07T08:21:15", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-07T22:44:14", - "normal": 8.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-08T06:58:25", - "normal": 4.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-08T08:16:59", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-08T13:52:10", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-08T19:52:08", - "normal": 5.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-08T19:52:08", - "normal": 5.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T06:26:22", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T06:26:22", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T07:43:04", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T15:08:46", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T15:54:44", - "normal": 3.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T23:03:47", - "normal": 4.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T23:38:04", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-09T23:38:04", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-10T16:02:43", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-10T22:56:35", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-10T22:56:35", - "normal": 3.45, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-10T23:35:59", - "normal": 2.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-11T15:03:25", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-11T15:03:25", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-11T16:13:04", - "normal": 2.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-11T21:19:03", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-11T21:19:03", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T07:22:58", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T15:16:54", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T15:16:54", - "normal": 3.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T15:54:25", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T21:11:04", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-12T21:11:04", - "normal": 4.05, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T13:15:55", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T13:18:43", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T13:18:43", - "normal": 5.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T16:26:19", - "normal": 6.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T16:26:19", - "normal": 6.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T20:33:47", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T20:33:47", - "normal": 8.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T20:49:06", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T21:24:48", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T23:18:40", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-13T23:45:17", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T00:25:53", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T01:10:52", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T12:00:00", - "normal": 3.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T15:36:08", - "normal": 1.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T16:01:10", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T19:58:59", - "normal": 3.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T20:51:48", - "normal": 8.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T20:51:48", - "normal": 8.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T21:40:26", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-14T23:14:13", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T00:33:52", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T00:33:52", - "normal": 3.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T08:45:17", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T15:49:05", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T21:53:25", - "normal": 8.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T21:53:25", - "normal": 8.75, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-15T22:38:18", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-16T16:47:33", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-16T22:22:47", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-16T23:27:48", - "normal": 14.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-17T15:50:12", - "normal": 3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-17T15:52:31", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T14:12:19", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T15:09:54", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T15:27:12", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T15:57:46", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T23:28:05", - "normal": 8.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-18T23:28:05", - "normal": 8.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T00:10:14", - "normal": 5.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T00:46:24", - "normal": 5.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T01:11:02", - "normal": 5.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T14:59:14", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T16:28:00", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T22:00:22", - "normal": 6.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-19T23:24:34", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T17:39:33", - "normal": 4.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T19:27:43", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T20:07:49", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T20:43:12", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-20T21:54:33", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-21T14:16:42", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-21T20:42:35", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-22T12:14:12", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T07:12:15", - "normal": 3.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T11:12:32", - "normal": 1.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T12:36:16", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T12:50:53", - "normal": 8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-23T14:17:09", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-24T10:47:06", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-24T14:20:06", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-24T16:11:40", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-25T00:18:43", - "normal": 0.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-25T19:12:42", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-25T19:12:42", - "normal": 3.95, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-25T20:42:26", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-25T20:42:26", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-26T18:49:01", - "normal": 4.6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-27T18:11:11", - "normal": 2.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-27T20:47:51", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-28T13:28:57", - "normal": 1.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-28T13:31:35", - "normal": 5.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-28T13:43:39", - "normal": 1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-28T18:08:08", - "normal": 2.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-29T03:56:45", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-29T03:56:45", - "normal": 4.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-29T15:09:37", - "normal": 5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-29T15:58:27", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-29T15:58:27", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-30T02:57:09", - "normal": 4.8, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-30T16:34:05", - "normal": 10, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-30T19:17:07", - "expectedNormal": 8, - "normal": 6.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-30T23:28:05", - "normal": 1.3, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-10-31T20:19:12", - "normal": 6, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-01T16:10:05", - "normal": 7, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-01T23:01:05", - "normal": 3.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-01T23:01:05", - "normal": 3.15, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-02T17:16:10", - "normal": 4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-02T23:46:20", - "normal": 8.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-03T12:56:37", - "normal": 6.1, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-03T13:09:30", - "normal": 7.4, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-03T16:07:02", - "normal": 1.5, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-03T20:10:25", - "duration": 3600000, - "extended": 2.2, - "normal": 12.3, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-03T20:10:25", - "duration": 3600000, - "extended": 2.2, - "normal": 12.3, - "subType": "dual/square", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T05:00:38", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T05:00:38", - "normal": 3.55, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T12:35:17", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T12:35:17", - "normal": 1.9, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T15:46:38", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T15:46:38", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-04T22:01:14", - "normal": 4.2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-05T09:37:58", - "normal": 2, - "subType": "normal", - }, - { - "deviceId": "some-other-pump", - "deviceTime": "2018-11-05T13:19:18", - "normal": 2, - "subType": "normal", - }, -} - -var jfBasalStr = `[ - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T22:00:00", - "duration": 1217000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T22:20:17", - "duration": 800000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T22:33:37", - "duration": 5183000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T00:00:00", - "duration": 7992000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T02:13:12", - "duration": 2334000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T05:52:06", - "duration": 6987000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T07:48:33", - "duration": 1140000, - "percent": 0.4, - "rate": 0.62, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T07:48:33", - "duration": 1140000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-11-15T12:49:31Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T07:48:33", - "duration": 1109000, - "expectedDuration": 1140000, - "percent": 0.4, - "rate": 0.62, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T07:48:33", - "duration": 1140000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-11-15T12:49:31Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T08:07:02", - "duration": 2631000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T08:50:53", - "duration": 8779000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:17:12", - "duration": 1800000, - "percent": 0.6, - "rate": 0.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:17:12", - "duration": 1800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-15T16:18:10Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:47:12", - "duration": 592000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:57:04", - "duration": 7200000, - "percent": 0.35, - "rate": 0.5, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:57:04", - "duration": 7200000, - "rate": 1.43, - "scheduleName": "basal 3", - "time": "2017-11-15T16:58:02Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:57:04", - "duration": 176000, - "expectedDuration": 7200000, - "percent": 0.35, - "rate": 0.5, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:57:04", - "duration": 7200000, - "rate": 1.43, - "scheduleName": "basal 3", - "time": "2017-11-15T16:58:02Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T12:00:00", - "duration": 7200000, - "percent": 0.35, - "rate": 0.22, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T12:00:00", - "duration": 7200000, - "rate": 0.63, - "scheduleName": "basal 3", - "time": "2017-11-15T17:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T12:00:00", - "duration": 7024000, - "expectedDuration": 7200000, - "percent": 0.35, - "rate": 0.22, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T12:00:00", - "duration": 7200000, - "rate": 0.63, - "scheduleName": "basal 3", - "time": "2017-11-15T17:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T13:57:04", - "duration": 14576000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T08:30:00", - "duration": 3356000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T09:25:56", - "duration": 7200000, - "percent": 0.5, - "rate": 0.72, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T09:25:56", - "duration": 7200000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2017-11-16T14:26:54Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T11:25:56", - "duration": 2044000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T12:00:00", - "duration": 1425000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T12:23:45", - "duration": 5400000, - "percent": 0.5, - "rate": 0.32, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T12:23:45", - "duration": 5400000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2017-11-16T17:24:43Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T13:53:45", - "duration": 14775000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T00:00:00", - "duration": 2543000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T00:42:23", - "duration": 12600000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T00:42:23", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-17T05:43:21Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T00:42:23", - "duration": 10057000, - "expectedDuration": 12600000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T00:42:23", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-17T05:43:21Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T03:30:00", - "duration": 12600000, - "percent": 0.65, - "rate": 0.84, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T03:30:00", - "duration": 12600000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2017-11-17T08:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T03:30:00", - "duration": 2543000, - "expectedDuration": 12600000, - "percent": 0.65, - "rate": 0.84, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T03:30:00", - "duration": 12600000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2017-11-17T08:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T04:12:23", - "duration": 4657000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T08:30:00", - "duration": 10937000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T11:32:17", - "duration": 10800000, - "percent": 0.6, - "rate": 0.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T11:32:17", - "duration": 10800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-17T16:33:15Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T11:32:17", - "duration": 1663000, - "expectedDuration": 10800000, - "percent": 0.6, - "rate": 0.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T11:32:17", - "duration": 10800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-17T16:33:15Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T12:00:00", - "duration": 7860000, - "percent": 0.6, - "rate": 0.39, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T12:00:00", - "duration": 7860000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-11-17T17:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T12:00:00", - "duration": 6157000, - "expectedDuration": 7860000, - "percent": 0.6, - "rate": 0.39, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T12:00:00", - "duration": 7860000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-11-17T17:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T13:42:37", - "duration": 47000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T13:43:24", - "duration": 10800000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T13:43:24", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-11-17T18:44:22Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T16:43:24", - "duration": 4596000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T18:00:00", - "duration": 2896000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T18:48:16", - "duration": 4862000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T20:09:18", - "duration": 6642000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T00:00:00", - "duration": 10582000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T02:56:22", - "duration": 21600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T02:56:22", - "duration": 21600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-20T07:57:20Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T02:56:22", - "duration": 2018000, - "expectedDuration": 21600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T02:56:22", - "duration": 21600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-20T07:57:20Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T03:30:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T03:30:00", - "duration": 21600000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-11-20T08:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T03:30:00", - "duration": 7200000, - "expectedDuration": 21600000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T03:30:00", - "duration": 21600000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-11-20T08:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T05:30:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T05:30:00", - "duration": 21600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-11-20T10:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T05:30:00", - "duration": 10800000, - "expectedDuration": 21600000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T05:30:00", - "duration": 21600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-11-20T10:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T08:30:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T08:30:00", - "duration": 21600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-20T13:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T08:30:00", - "duration": 1582000, - "expectedDuration": 21600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T08:30:00", - "duration": 21600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-20T13:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T08:56:22", - "duration": 11018000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T12:00:00", - "duration": 7848000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T14:10:48", - "duration": 9000000, - "percent": 1.25, - "rate": 0.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T14:10:48", - "duration": 9000000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-11-20T19:11:46Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T16:40:48", - "duration": 4752000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T18:00:00", - "duration": 4786000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T19:19:46", - "duration": 492000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T19:27:58", - "duration": 9122000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T08:30:00", - "duration": 5770000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:06:10", - "duration": 1860000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:06:10", - "duration": 1860000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-22T15:07:08Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:06:10", - "duration": 1803000, - "expectedDuration": 1860000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:06:10", - "duration": 1860000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-22T15:07:08Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:36:13", - "duration": 13000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:36:26", - "duration": 3600000, - "percent": 1.15, - "rate": 1.66, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:36:26", - "duration": 3600000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2017-11-22T15:37:24Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T11:36:26", - "duration": 1414000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T12:00:00", - "duration": 19357000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T17:22:37", - "duration": 385000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T17:29:02", - "duration": 1858000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T12:00:00", - "duration": 499000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T12:08:19", - "duration": 9000000, - "percent": 0.55, - "rate": 0.35, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T12:08:19", - "duration": 9000000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2017-11-23T17:09:17Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T14:38:19", - "duration": 8117000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T16:53:36", - "duration": 5400000, - "percent": 1.5, - "rate": 0.97, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T16:53:36", - "duration": 5400000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-11-23T21:54:34Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T16:53:36", - "duration": 3984000, - "expectedDuration": 5400000, - "percent": 1.5, - "rate": 0.97, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T16:53:36", - "duration": 5400000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-11-23T21:54:34Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T18:00:00", - "duration": 5400000, - "percent": 1.5, - "rate": 1.72, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T18:00:00", - "duration": 5400000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2017-11-23T23:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T18:00:00", - "duration": 1416000, - "expectedDuration": 5400000, - "percent": 1.5, - "rate": 1.72, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T18:00:00", - "duration": 5400000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2017-11-23T23:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T18:23:36", - "duration": 12984000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T22:00:00", - "duration": 1335000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T22:22:15", - "duration": 7200000, - "percent": 0.7, - "rate": 0.91, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T22:22:15", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-11-24T03:23:13Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T22:22:15", - "duration": 5865000, - "expectedDuration": 7200000, - "percent": 0.7, - "rate": 0.91, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T22:22:15", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-11-24T03:23:13Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T00:00:00", - "duration": 7200000, - "percent": 0.7, - "rate": 1.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T00:00:00", - "duration": 7200000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2017-11-24T05:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T00:00:00", - "duration": 1335000, - "expectedDuration": 7200000, - "percent": 0.7, - "rate": 1.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T00:00:00", - "duration": 7200000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2017-11-24T05:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T00:22:15", - "duration": 5651000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T01:56:26", - "duration": 16200000, - "percent": 0.5, - "rate": 0.72, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T01:56:26", - "duration": 16200000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2017-11-24T06:57:24Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T01:56:26", - "duration": 5614000, - "expectedDuration": 16200000, - "percent": 0.5, - "rate": 0.72, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T01:56:26", - "duration": 16200000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2017-11-24T06:57:24Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:30:00", - "duration": 6360000, - "percent": 0.5, - "rate": 0.65, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:30:00", - "duration": 6360000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-11-24T08:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:30:00", - "duration": 713000, - "expectedDuration": 6360000, - "percent": 0.5, - "rate": 0.65, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:30:00", - "duration": 6360000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-11-24T08:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:41:53", - "duration": 14000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:42:07", - "duration": 480000, - "percent": 0.15000000000000002, - "rate": 0.19, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:42:07", - "duration": 480000, - "rate": 1.27, - "scheduleName": "basal 3", - "time": "2017-11-24T08:43:05Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:42:07", - "duration": 453000, - "expectedDuration": 480000, - "percent": 0.15000000000000002, - "rate": 0.19, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:42:07", - "duration": 480000, - "rate": 1.27, - "scheduleName": "basal 3", - "time": "2017-11-24T08:43:05Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:49:40", - "duration": 21000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:50:01", - "duration": 1260000, - "rate": 0 - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:50:01", - "duration": 1243000, - "expectedDuration": 1260000, - "rate": 0 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T04:10:44", - "duration": 17000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T04:11:01", - "duration": 25200000, - "percent": 0.30000000000000004, - "rate": 0.39, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T04:11:01", - "duration": 25200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-11-24T09:11:59Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T04:11:01", - "duration": 4739000, - "expectedDuration": 25200000, - "percent": 0.30000000000000004, - "rate": 0.39, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T04:11:01", - "duration": 25200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-11-24T09:11:59Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T05:30:00", - "duration": 25200000, - "percent": 0.30000000000000004, - "rate": 0.46, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T05:30:00", - "duration": 25200000, - "rate": 1.53, - "scheduleName": "basal 3", - "time": "2017-11-24T10:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T05:30:00", - "duration": 10800000, - "expectedDuration": 25200000, - "percent": 0.30000000000000004, - "rate": 0.46, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T05:30:00", - "duration": 25200000, - "rate": 1.53, - "scheduleName": "basal 3", - "time": "2017-11-24T10:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T08:30:00", - "duration": 21000000, - "percent": 0.30000000000000004, - "rate": 0.43, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T08:30:00", - "duration": 21000000, - "rate": 1.43, - "scheduleName": "basal 3", - "time": "2017-11-24T13:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T08:30:00", - "duration": 5443000, - "expectedDuration": 21000000, - "percent": 0.30000000000000004, - "rate": 0.43, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T08:30:00", - "duration": 21000000, - "rate": 1.43, - "scheduleName": "basal 3", - "time": "2017-11-24T13:30:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T10:00:43", - "duration": 7157000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T08:30:00", - "duration": 7831000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T10:40:31", - "duration": 3660000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T10:40:31", - "duration": 3660000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-25T15:41:29Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T10:40:31", - "duration": 3630000, - "expectedDuration": 3660000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T10:40:31", - "duration": 3660000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-25T15:41:29Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T11:41:01", - "duration": 26048000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T18:55:09", - "duration": 11091000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T08:30:00", - "duration": 4143000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T09:39:03", - "duration": 5400000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T09:39:03", - "duration": 5400000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-11-26T14:40:01Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T11:09:03", - "duration": 3057000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T12:00:00", - "duration": 11173000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T15:06:13", - "duration": 10800000, - "percent": 0.5, - "rate": 0.32, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T15:06:13", - "duration": 10800000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2017-11-27T20:07:11Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T15:06:13", - "duration": 10427000, - "expectedDuration": 10800000, - "percent": 0.5, - "rate": 0.32, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T15:06:13", - "duration": 10800000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2017-11-27T20:07:11Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T18:00:00", - "duration": 10800000, - "percent": 0.5, - "rate": 0.57, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T18:00:00", - "duration": 10800000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2017-11-27T23:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T18:00:00", - "duration": 373000, - "expectedDuration": 10800000, - "percent": 0.5, - "rate": 0.57, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T18:00:00", - "duration": 10800000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2017-11-27T23:00:58Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T18:06:13", - "duration": 14027000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T05:30:00", - "duration": 7330000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T07:32:10", - "duration": 8320000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T09:50:50", - "duration": 7750000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T12:00:00", - "duration": 13768000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T15:49:28", - "duration": 1919000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T13:21:27", - "duration": 16713000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T18:00:00", - "duration": 7752000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T20:09:12", - "duration": 4951000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T21:31:43", - "duration": 1697000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T05:30:00", - "duration": 2075000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T06:04:35", - "duration": 5400000, - "percent": 1.4, - "rate": 2.17, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T06:04:35", - "duration": 5400000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-12-01T14:05:33Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T07:34:35", - "duration": 3325000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T08:30:00", - "duration": 6166000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T10:12:46", - "duration": 5400000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T10:12:46", - "duration": 5400000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-01T18:13:44Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T11:42:46", - "duration": 1034000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T22:00:00", - "duration": 4345000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T23:12:25", - "duration": 1767000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T23:41:52", - "duration": 1088000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T05:30:00", - "duration": 7632000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T07:37:12", - "duration": 7359000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T09:39:51", - "duration": 8409000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T08:30:00", - "duration": 7692000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T10:38:12", - "duration": 1864000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T11:09:16", - "duration": 3044000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T18:00:00", - "duration": 11017000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T21:03:37", - "duration": 10800000, - "percent": 1.5, - "rate": 1.72, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T21:03:37", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2017-12-13T05:04:35Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T21:03:37", - "duration": 3383000, - "expectedDuration": 10800000, - "percent": 1.5, - "rate": 1.72, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T21:03:37", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2017-12-13T05:04:35Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T22:00:00", - "duration": 10800000, - "percent": 1.5, - "rate": 1.95, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T22:00:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-13T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T22:00:00", - "duration": 7200000, - "expectedDuration": 10800000, - "percent": 1.5, - "rate": 1.95, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T22:00:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-13T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T00:00:00", - "duration": 10800000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T00:00:00", - "duration": 10800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-13T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T00:00:00", - "duration": 217000, - "expectedDuration": 10800000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T00:00:00", - "duration": 10800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-13T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T00:03:37", - "duration": 12383000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T05:30:00", - "duration": 5676000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T07:04:36", - "duration": 7200000, - "percent": 0.4, - "rate": 0.62, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T07:04:36", - "duration": 7200000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-12-13T15:05:34Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T07:04:36", - "duration": 5124000, - "expectedDuration": 7200000, - "percent": 0.4, - "rate": 0.62, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T07:04:36", - "duration": 7200000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-12-13T15:05:34Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T08:30:00", - "duration": 7200000, - "percent": 0.4, - "rate": 0.58, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T08:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-13T16:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T08:30:00", - "duration": 2076000, - "expectedDuration": 7200000, - "percent": 0.4, - "rate": 0.58, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T08:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-13T16:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T09:04:36", - "duration": 8062000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T11:18:58", - "duration": 3600000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T11:18:58", - "duration": 3600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-13T19:19:56Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T11:18:58", - "duration": 2462000, - "expectedDuration": 3600000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T11:18:58", - "duration": 3600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-13T19:19:56Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T12:00:00", - "duration": 3600000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T12:00:00", - "duration": 3600000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-12-13T20:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T12:00:00", - "duration": 1138000, - "expectedDuration": 3600000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T12:00:00", - "duration": 3600000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-12-13T20:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T12:18:58", - "duration": 20462000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T18:00:00", - "duration": 3789000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T19:03:09", - "duration": 4406000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T20:16:35", - "duration": 6205000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T12:00:00", - "duration": 21479000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T17:57:59", - "duration": 7200000, - "percent": 1.45, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T17:57:59", - "duration": 7200000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-12-16T01:58:57Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T17:57:59", - "duration": 121000, - "expectedDuration": 7200000, - "percent": 1.45, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T17:57:59", - "duration": 7200000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2017-12-16T01:58:57Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T18:00:00", - "duration": 7200000, - "percent": 1.45, - "rate": 1.66, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T18:00:00", - "duration": 7200000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2017-12-16T02:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T18:00:00", - "duration": 7079000, - "expectedDuration": 7200000, - "percent": 1.45, - "rate": 1.66, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T18:00:00", - "duration": 7200000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2017-12-16T02:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T19:57:59", - "duration": 7321000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T03:30:00", - "duration": 6942000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:25:42", - "duration": 5400000, - "percent": 1.5, - "rate": 1.95, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:25:42", - "duration": 5400000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-16T13:26:40Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:25:42", - "duration": 258000, - "expectedDuration": 5400000, - "percent": 1.5, - "rate": 1.95, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:25:42", - "duration": 5400000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-16T13:26:40Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:30:00", - "duration": 5400000, - "percent": 1.5, - "rate": 2.32, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:30:00", - "duration": 5400000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-12-16T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:30:00", - "duration": 5142000, - "expectedDuration": 5400000, - "percent": 1.5, - "rate": 2.32, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:30:00", - "duration": 5400000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-12-16T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T06:55:42", - "duration": 5658000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T18:00:00", - "duration": 12497000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T21:28:17", - "duration": 2135000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T22:03:52", - "duration": 6968000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T00:00:00", - "duration": 4032000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T01:07:12", - "duration": 7200000, - "percent": 1.75, - "rate": 2.53, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T01:07:12", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-17T09:08:10Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T03:07:12", - "duration": 1368000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T22:00:00", - "duration": 4835000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T23:20:35", - "duration": 5400000, - "percent": 1.5, - "rate": 1.95, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T23:20:35", - "duration": 5400000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-19T07:21:33Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T23:20:35", - "duration": 2365000, - "expectedDuration": 5400000, - "percent": 1.5, - "rate": 1.95, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T23:20:35", - "duration": 5400000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-19T07:21:33Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T00:00:00", - "duration": 5400000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T00:00:00", - "duration": 5400000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-19T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T00:00:00", - "duration": 3035000, - "expectedDuration": 5400000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T00:00:00", - "duration": 5400000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-19T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T00:50:35", - "duration": 9565000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T05:30:00", - "duration": 1701000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T05:58:21", - "duration": 50296000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T19:56:37", - "duration": 7403000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T18:00:00", - "duration": 8649000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T20:24:09", - "duration": 9000000, - "percent": 1.95, - "rate": 2.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T20:24:09", - "duration": 9000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2017-12-23T04:25:07Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T20:24:09", - "duration": 5751000, - "expectedDuration": 9000000, - "percent": 1.95, - "rate": 2.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T20:24:09", - "duration": 9000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2017-12-23T04:25:07Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T22:00:00", - "duration": 9000000, - "percent": 1.95, - "rate": 2.53, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T22:00:00", - "duration": 9000000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-23T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T22:00:00", - "duration": 3249000, - "expectedDuration": 9000000, - "percent": 1.95, - "rate": 2.53, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T22:00:00", - "duration": 9000000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-23T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T22:54:09", - "duration": 3951000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T18:00:00", - "duration": 366000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T18:06:06", - "duration": 613000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T18:16:19", - "duration": 13421000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T03:30:00", - "duration": 5480000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:01:20", - "duration": 12600000, - "percent": 1.6, - "rate": 2.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:01:20", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-25T13:02:18Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:01:20", - "duration": 1720000, - "expectedDuration": 12600000, - "percent": 1.6, - "rate": 2.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:01:20", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-25T13:02:18Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:30:00", - "duration": 12600000, - "percent": 1.6, - "rate": 2.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:30:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-12-25T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:30:00", - "duration": 10800000, - "expectedDuration": 12600000, - "percent": 1.6, - "rate": 2.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:30:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-12-25T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T08:30:00", - "duration": 12600000, - "percent": 1.6, - "rate": 2.32, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-25T16:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T08:30:00", - "duration": 80000, - "expectedDuration": 12600000, - "percent": 1.6, - "rate": 2.32, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-25T16:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T08:31:20", - "duration": 12520000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T05:30:00", - "duration": 3692000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T06:31:32", - "duration": 14400000, - "percent": 1.65, - "rate": 2.55, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T06:31:32", - "duration": 14400000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-12-26T14:32:30Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T06:31:32", - "duration": 7108000, - "expectedDuration": 14400000, - "percent": 1.65, - "rate": 2.55, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T06:31:32", - "duration": 14400000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2017-12-26T14:32:30Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T08:30:00", - "duration": 14400000, - "percent": 1.65, - "rate": 2.39, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T08:30:00", - "duration": 14400000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-26T16:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T08:30:00", - "duration": 7292000, - "expectedDuration": 14400000, - "percent": 1.65, - "rate": 2.39, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T08:30:00", - "duration": 14400000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-26T16:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T10:31:32", - "duration": 5308000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T18:00:00", - "duration": 9007000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T20:30:07", - "duration": 4826000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T21:50:33", - "duration": 567000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T12:00:00", - "duration": 175000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T12:02:55", - "duration": 203000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T12:06:18", - "duration": 21222000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T22:00:00", - "duration": 5252000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T23:27:32", - "duration": 7200000, - "percent": 1.45, - "rate": 1.88, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T23:27:32", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-31T07:28:30Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T23:27:32", - "duration": 1948000, - "expectedDuration": 7200000, - "percent": 1.45, - "rate": 1.88, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T23:27:32", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2017-12-31T07:28:30Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T00:00:00", - "duration": 7200000, - "percent": 1.45, - "rate": 2.1, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T00:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-31T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T00:00:00", - "duration": 5252000, - "expectedDuration": 7200000, - "percent": 1.45, - "rate": 2.1, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T00:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2017-12-31T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T01:27:32", - "duration": 7348000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T05:30:00", - "duration": 10163000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T08:19:23", - "duration": 227000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T08:23:10", - "duration": 410000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T08:30:00", - "duration": 1916000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T09:01:56", - "duration": 291000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T09:06:47", - "duration": 10393000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T00:00:00", - "duration": 2058000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T00:34:18", - "duration": 18000000, - "percent": 1.3, - "rate": 1.88, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T00:34:18", - "duration": 18000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-01-05T08:35:16Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T00:34:18", - "duration": 10542000, - "expectedDuration": 18000000, - "percent": 1.3, - "rate": 1.88, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T00:34:18", - "duration": 18000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-01-05T08:35:16Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T03:30:00", - "duration": 18000000, - "percent": 1.3, - "rate": 1.69, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T03:30:00", - "duration": 18000000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-01-05T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T03:30:00", - "duration": 7200000, - "expectedDuration": 18000000, - "percent": 1.3, - "rate": 1.69, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T03:30:00", - "duration": 18000000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-01-05T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T05:30:00", - "duration": 18000000, - "percent": 1.3, - "rate": 2.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T05:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-01-05T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T05:30:00", - "duration": 258000, - "expectedDuration": 18000000, - "percent": 1.3, - "rate": 2.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T05:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-01-05T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T05:34:18", - "duration": 10542000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T00:00:00", - "duration": 5352000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T01:29:12", - "duration": 16200000, - "percent": 1.45, - "rate": 2.1, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T01:29:12", - "duration": 16200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-01-06T09:30:10Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T01:29:12", - "duration": 7248000, - "expectedDuration": 16200000, - "percent": 1.45, - "rate": 2.1, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T01:29:12", - "duration": 16200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-01-06T09:30:10Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T03:30:00", - "duration": 16200000, - "percent": 1.45, - "rate": 1.88, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T03:30:00", - "duration": 16200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-01-06T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T03:30:00", - "duration": 7200000, - "expectedDuration": 16200000, - "percent": 1.45, - "rate": 1.88, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T03:30:00", - "duration": 16200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-01-06T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T05:30:00", - "duration": 16200000, - "percent": 1.45, - "rate": 2.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T05:30:00", - "duration": 16200000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-01-06T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T05:30:00", - "duration": 1752000, - "expectedDuration": 16200000, - "percent": 1.45, - "rate": 2.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T05:30:00", - "duration": 16200000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-01-06T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T05:59:12", - "duration": 9048000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T08:30:00", - "duration": 10301000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T11:21:41", - "duration": 1674000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T11:49:35", - "duration": 625000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T12:00:00", - "duration": 10354000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T14:52:34", - "duration": 729000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T15:04:43", - "duration": 10517000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T05:30:00", - "duration": 6107000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T07:11:47", - "duration": 3600000, - "percent": 0.35, - "rate": 0.54, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T07:11:47", - "duration": 3600000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-01-10T15:12:45Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T08:11:47", - "duration": 1093000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T08:30:00", - "duration": 5259000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T09:57:39", - "duration": 54000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T09:58:33", - "duration": 7287000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T22:00:00", - "duration": 4793000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T23:19:53", - "duration": 5171000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T00:46:04", - "duration": 9836000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T12:00:00", - "duration": 19060000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T17:17:40", - "duration": 298000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T17:22:38", - "duration": 2242000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T18:00:00", - "duration": 762000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T18:12:42", - "duration": 364000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T18:18:46", - "duration": 13274000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T08:30:00", - "duration": 3806000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T09:33:26", - "duration": 32400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T09:33:26", - "duration": 32400000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-01-19T17:34:24Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T09:33:26", - "duration": 8794000, - "expectedDuration": 32400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T09:33:26", - "duration": 32400000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-01-19T17:34:24Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T12:00:00", - "duration": 32400000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T12:00:00", - "duration": 32400000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-01-19T20:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T12:00:00", - "duration": 21600000, - "expectedDuration": 32400000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T12:00:00", - "duration": 32400000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-01-19T20:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T18:00:00", - "duration": 32400000, - "percent": 0.75, - "rate": 0.86, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T18:00:00", - "duration": 32400000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-01-20T02:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T18:00:00", - "duration": 2006000, - "expectedDuration": 32400000, - "percent": 0.75, - "rate": 0.86, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T18:00:00", - "duration": 32400000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-01-20T02:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T18:33:26", - "duration": 12394000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T08:30:00", - "duration": 12207000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T11:53:27", - "duration": 10800000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T11:53:27", - "duration": 10800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-01-20T19:54:25Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T11:53:27", - "duration": 393000, - "expectedDuration": 10800000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T11:53:27", - "duration": 10800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-01-20T19:54:25Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T12:00:00", - "duration": 10800000, - "percent": 0.65, - "rate": 0.42, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T12:00:00", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-01-20T20:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T12:00:00", - "duration": 10407000, - "expectedDuration": 10800000, - "percent": 0.65, - "rate": 0.42, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T12:00:00", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-01-20T20:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T14:53:27", - "duration": 11193000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T00:00:00", - "duration": 4261000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T01:11:01", - "duration": 404000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T01:17:45", - "duration": 7935000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T08:30:00", - "duration": 1757000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T08:59:17", - "duration": 695000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T09:10:52", - "duration": 10148000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T12:00:00", - "duration": 18043000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T17:00:43", - "duration": 2404000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T17:40:47", - "duration": 1153000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T00:00:00", - "duration": 4572000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T01:16:12", - "duration": 303000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T01:21:15", - "duration": 7725000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T08:30:00", - "duration": 1219000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T08:50:19", - "duration": 5400000, - "percent": 1.3, - "rate": 1.88, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T08:50:19", - "duration": 5400000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-01-31T16:51:17Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T10:20:19", - "duration": 5981000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T12:00:00", - "duration": 14758000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T16:05:58", - "duration": 375000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T16:12:13", - "duration": 6467000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T18:00:00", - "duration": 11599000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T21:13:19", - "duration": 711000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T21:25:10", - "duration": 2090000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T18:00:00", - "duration": 10305000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T20:51:45", - "duration": 7200000, - "percent": 0.19999999999999996, - "rate": 0.23, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T20:51:45", - "duration": 7200000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-02-04T04:52:43Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T20:51:45", - "duration": 4095000, - "expectedDuration": 7200000, - "percent": 0.19999999999999996, - "rate": 0.23, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T20:51:45", - "duration": 7200000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-02-04T04:52:43Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T22:00:00", - "duration": 7200000, - "percent": 0.19999999999999996, - "rate": 0.28, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-02-04T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T22:00:00", - "duration": 3105000, - "expectedDuration": 7200000, - "percent": 0.19999999999999996, - "rate": 0.28, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-02-04T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T22:51:45", - "duration": 4095000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T12:00:00", - "duration": 19370000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T17:22:50", - "duration": 3600000, - "percent": 0.7, - "rate": 0.45, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T17:22:50", - "duration": 3600000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-02-06T01:23:48Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T17:22:50", - "duration": 2230000, - "expectedDuration": 3600000, - "percent": 0.7, - "rate": 0.45, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T17:22:50", - "duration": 3600000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-02-06T01:23:48Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T18:00:00", - "duration": 3600000, - "percent": 0.7, - "rate": 0.8, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T18:00:00", - "duration": 3600000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-02-06T02:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T18:00:00", - "duration": 1370000, - "expectedDuration": 3600000, - "percent": 0.7, - "rate": 0.8, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T18:00:00", - "duration": 3600000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-02-06T02:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T18:22:50", - "duration": 13030000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T03:30:00", - "duration": 7580000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T05:36:20", - "duration": 249000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T05:40:29", - "duration": 10171000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T08:30:00", - "duration": 169000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T08:32:49", - "duration": 544000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T08:41:53", - "duration": 11887000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T12:00:00", - "duration": 16275000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T16:31:15", - "duration": 455000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T16:38:50", - "duration": 4870000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T18:00:00", - "duration": 13413000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T21:43:33", - "duration": 246000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T21:47:39", - "duration": 741000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:00:00", - "duration": 643000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:10:43", - "duration": 60000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:10:43", - "duration": 60000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-15T08:11:41Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:10:43", - "duration": 7000, - "expectedDuration": 60000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:10:43", - "duration": 60000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-15T08:11:41Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:10:50", - "duration": 273000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:15:23", - "duration": 28000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:15:51", - "duration": 7200000, - "percent": 1.3, - "rate": 1.95, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:15:51", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-15T08:16:49Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T02:15:51", - "duration": 4449000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T00:00:00", - "duration": 10840000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:00:40", - "duration": 10800000, - "percent": 1.45, - "rate": 2.17, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:00:40", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-16T11:01:38Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:00:40", - "duration": 1760000, - "expectedDuration": 10800000, - "percent": 1.45, - "rate": 2.17, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:00:40", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-16T11:01:38Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:30:00", - "duration": 10800000, - "percent": 1.45, - "rate": 1.95, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:30:00", - "duration": 10800000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-02-16T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:30:00", - "duration": 7200000, - "expectedDuration": 10800000, - "percent": 1.45, - "rate": 1.95, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:30:00", - "duration": 10800000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-02-16T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T05:30:00", - "duration": 10800000, - "percent": 1.45, - "rate": 2.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T05:30:00", - "duration": 10800000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-02-16T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T05:30:00", - "duration": 1840000, - "expectedDuration": 10800000, - "percent": 1.45, - "rate": 2.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T05:30:00", - "duration": 10800000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-02-16T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T06:00:40", - "duration": 8960000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T05:30:00", - "duration": 9662000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T08:11:02", - "duration": 6831000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T10:04:53", - "duration": 973000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T10:21:06", - "duration": 97000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T10:22:43", - "duration": 5837000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T12:00:00", - "duration": 4664000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T13:17:44", - "duration": 7380000, - "percent": 1.5, - "rate": 0.97, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T13:17:44", - "duration": 7380000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-02-18T21:18:42Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T13:17:44", - "duration": 7325000, - "expectedDuration": 7380000, - "percent": 1.5, - "rate": 0.97, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T13:17:44", - "duration": 7380000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-02-18T21:18:42Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T15:19:49", - "duration": 9611000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T22:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T22:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T22:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T05:30:00", - "duration": 7957000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T07:42:37", - "duration": 35000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T07:43:12", - "duration": 2808000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T08:30:00", - "duration": 8781000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T10:56:21", - "duration": 254000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T11:00:35", - "duration": 3565000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T00:00:00", - "duration": 4542000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T01:15:42", - "duration": 10800000, - "percent": 0.7, - "rate": 1.05, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T01:15:42", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-22T09:16:40Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T01:15:42", - "duration": 8058000, - "expectedDuration": 10800000, - "percent": 0.7, - "rate": 1.05, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T01:15:42", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-22T09:16:40Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T03:30:00", - "duration": 10800000, - "percent": 0.7, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T03:30:00", - "duration": 10800000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-02-22T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T03:30:00", - "duration": 2742000, - "expectedDuration": 10800000, - "percent": 0.7, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T03:30:00", - "duration": 10800000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-02-22T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T04:15:42", - "duration": 4458000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T18:00:00", - "duration": 366000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T18:06:06", - "duration": 21600000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T18:06:06", - "duration": 21600000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-02-23T02:07:04Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T18:06:06", - "duration": 14034000, - "expectedDuration": 21600000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T18:06:06", - "duration": 21600000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-02-23T02:07:04Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T22:00:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T22:00:00", - "duration": 21600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-02-23T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T22:00:00", - "duration": 7200000, - "expectedDuration": 21600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T22:00:00", - "duration": 21600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-02-23T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T00:00:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T00:00:00", - "duration": 21600000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-23T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T00:00:00", - "duration": 366000, - "expectedDuration": 21600000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T00:00:00", - "duration": 21600000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-23T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T00:06:06", - "duration": 9204000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T02:39:30", - "duration": 18000000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T02:39:30", - "duration": 18000000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-23T10:40:28Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T02:39:30", - "duration": 3030000, - "expectedDuration": 18000000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T02:39:30", - "duration": 18000000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-23T10:40:28Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T03:30:00", - "duration": 18000000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T03:30:00", - "duration": 18000000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-02-23T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T03:30:00", - "duration": 7200000, - "expectedDuration": 18000000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T03:30:00", - "duration": 18000000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-02-23T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T05:30:00", - "duration": 18000000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T05:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-02-23T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T05:30:00", - "duration": 7770000, - "expectedDuration": 18000000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T05:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-02-23T13:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T07:39:30", - "duration": 3030000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T08:30:00", - "duration": 8164000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T10:46:04", - "duration": 18000000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T10:46:04", - "duration": 18000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-02-23T18:47:02Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T10:46:04", - "duration": 4436000, - "expectedDuration": 18000000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T10:46:04", - "duration": 18000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-02-23T18:47:02Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T12:00:00", - "duration": 18000000, - "percent": 0.65, - "rate": 0.42, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T12:00:00", - "duration": 18000000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-02-23T20:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T12:00:00", - "duration": 13564000, - "expectedDuration": 18000000, - "percent": 0.65, - "rate": 0.42, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T12:00:00", - "duration": 18000000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-02-23T20:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T15:46:04", - "duration": 8036000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T12:00:00", - "duration": 21410000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T17:56:50", - "duration": 2163000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T18:32:53", - "duration": 12427000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T22:00:00", - "duration": 5415000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T23:30:15", - "duration": 7200000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T23:30:15", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-02-26T07:31:13Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T23:30:15", - "duration": 1785000, - "expectedDuration": 7200000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T23:30:15", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-02-26T07:31:13Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T00:00:00", - "duration": 7200000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T00:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-26T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T00:00:00", - "duration": 5415000, - "expectedDuration": 7200000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T00:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-02-26T08:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T01:30:15", - "duration": 7185000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T08:30:00", - "duration": 345000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T08:35:45", - "duration": 5400000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T08:35:45", - "duration": 5400000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-02-27T16:36:43Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T10:05:45", - "duration": 6855000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T18:00:00", - "duration": 9705000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T20:41:45", - "duration": 7200000, - "percent": 1.3, - "rate": 1.49, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T20:41:45", - "duration": 7200000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-02-28T04:42:43Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T20:41:45", - "duration": 4695000, - "expectedDuration": 7200000, - "percent": 1.3, - "rate": 1.49, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T20:41:45", - "duration": 7200000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-02-28T04:42:43Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T22:00:00", - "duration": 7200000, - "percent": 1.3, - "rate": 1.88, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-02-28T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T22:00:00", - "duration": 2505000, - "expectedDuration": 7200000, - "percent": 1.3, - "rate": 1.88, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-02-28T06:00:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T22:41:45", - "duration": 4695000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T00:00:00", - "duration": 5211000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T01:26:51", - "duration": 199000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T01:30:10", - "duration": 147000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T01:32:37", - "duration": 12600000, - "percent": 0.75, - "rate": 1.12, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T01:32:37", - "duration": 12600000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-02-28T09:33:35Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T01:32:37", - "duration": 7043000, - "expectedDuration": 12600000, - "percent": 0.75, - "rate": 1.12, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T01:32:37", - "duration": 12600000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-02-28T09:33:35Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T03:30:00", - "duration": 12600000, - "percent": 0.75, - "rate": 1.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T03:30:00", - "duration": 12600000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-02-28T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T03:30:00", - "duration": 5557000, - "expectedDuration": 12600000, - "percent": 0.75, - "rate": 1.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T03:30:00", - "duration": 12600000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-02-28T11:30:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T05:02:37", - "duration": 1643000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T12:00:00", - "duration": 91000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T12:01:31", - "duration": 7200000, - "percent": 1.35, - "rate": 0.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T12:01:31", - "duration": 7200000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-03-02T20:02:29Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T14:01:31", - "duration": 14309000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T00:00:00", - "duration": 8771000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T02:26:11", - "duration": 272000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T02:30:43", - "duration": 3557000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T08:30:00", - "duration": 5906000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T10:08:26", - "duration": 2274000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T10:46:20", - "duration": 4420000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T18:00:00", - "duration": 2434000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T18:40:34", - "duration": 3332000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T19:36:06", - "duration": 8634000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T22:00:00", - "duration": 7042000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T23:57:22", - "duration": 114000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T23:59:16", - "duration": 44000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T08:30:00", - "duration": 135000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T08:32:15", - "duration": 360000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T09:38:15", - "duration": 8505000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T00:00:00", - "duration": 5721000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T01:35:21", - "duration": 660000, - "percent": 0.6, - "rate": 0.9, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T01:35:21", - "duration": 660000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-03-14T08:36:19Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T01:35:21", - "duration": 638000, - "expectedDuration": 660000, - "percent": 0.6, - "rate": 0.9, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T01:35:21", - "duration": 660000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-03-14T08:36:19Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T01:45:59", - "duration": 6241000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T18:00:00", - "duration": 12763000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T21:32:43", - "duration": 200000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T21:36:03", - "duration": 1437000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T00:00:00", - "duration": 7717000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T02:08:37", - "duration": 9000000, - "percent": 1.2, - "rate": 1.8, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T02:08:37", - "duration": 9000000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-03-16T09:09:35Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T02:08:37", - "duration": 4883000, - "expectedDuration": 9000000, - "percent": 1.2, - "rate": 1.8, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T02:08:37", - "duration": 9000000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-03-16T09:09:35Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T03:30:00", - "duration": 9000000, - "percent": 1.2, - "rate": 1.62, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T03:30:00", - "duration": 9000000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-03-16T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T03:30:00", - "duration": 4117000, - "expectedDuration": 9000000, - "percent": 1.2, - "rate": 1.62, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T03:30:00", - "duration": 9000000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-03-16T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T04:38:37", - "duration": 3083000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T00:00:00", - "duration": 1387000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T00:23:07", - "duration": 5575000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T01:56:02", - "duration": 5638000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T00:00:00", - "duration": 5074000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T01:24:34", - "duration": 3600000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T01:24:34", - "duration": 3600000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-03-20T08:25:32Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T02:24:34", - "duration": 3926000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T12:00:00", - "duration": 14636000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T16:03:56", - "duration": 156000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T16:06:32", - "duration": 6808000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T12:00:00", - "duration": 261000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T12:04:21", - "duration": 241000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T12:08:22", - "duration": 21098000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T08:30:00", - "duration": 5750000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T10:05:50", - "duration": 188000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T10:08:58", - "duration": 6662000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T12:00:00", - "duration": 17191000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T16:46:31", - "duration": 4727000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T18:05:18", - "duration": 14082000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T18:00:00", - "duration": 2581000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T18:43:01", - "duration": 67000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T21:44:08", - "duration": 952000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T18:00:00", - "duration": 9738000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T20:42:18", - "duration": 1004000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T20:59:02", - "duration": 3658000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T00:00:00", - "duration": 12403000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:26:43", - "duration": 7200000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:26:43", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-03-30T07:27:41Z", - "timezoneOffset": -180, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:26:43", - "duration": 197000, - "expectedDuration": 7200000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:26:43", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-03-30T07:27:41Z", - "timezoneOffset": -180, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:30:00", - "duration": 7200000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-03-30T07:30:58Z", - "timezoneOffset": -180, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:30:00", - "duration": 7003000, - "expectedDuration": 7200000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-03-30T07:30:58Z", - "timezoneOffset": -180, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T05:26:43", - "duration": 197000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T18:00:00", - "duration": 3804000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T19:03:24", - "duration": 476000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T19:11:20", - "duration": 10120000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T08:30:00", - "duration": 3078000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T09:21:18", - "duration": 5400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T09:21:18", - "duration": 5400000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-04-03T13:22:16Z", - "timezoneOffset": -180, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T10:51:18", - "duration": 4122000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T18:00:00", - "duration": 8562000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T20:22:42", - "duration": 87000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T17:24:09", - "duration": 2151000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T18:00:00", - "duration": 10423000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T20:53:43", - "duration": 2326000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T21:32:29", - "duration": 1651000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T08:30:00", - "duration": 11164000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T11:36:04", - "duration": 7381000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T13:39:05", - "duration": 15655000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T18:00:00", - "duration": 6679000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T19:51:19", - "duration": 1653000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T20:18:52", - "duration": 6068000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T08:30:00", - "duration": 6131000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T10:12:11", - "duration": 1800000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T10:12:11", - "duration": 1800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-04-10T17:13:09Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T10:42:11", - "duration": 4669000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T12:00:00", - "duration": 243000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T12:04:03", - "duration": 36000000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T12:04:03", - "duration": 36000000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-04-11T19:05:01Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T12:04:03", - "duration": 21357000, - "expectedDuration": 36000000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T12:04:03", - "duration": 36000000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-04-11T19:05:01Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T18:00:00", - "duration": 36000000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T18:00:00", - "duration": 36000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-04-12T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T18:00:00", - "duration": 14400000, - "expectedDuration": 36000000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T18:00:00", - "duration": 36000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-04-12T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T22:00:00", - "duration": 36000000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T22:00:00", - "duration": 36000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-04-12T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T22:00:00", - "duration": 242000, - "expectedDuration": 36000000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T22:00:00", - "duration": 36000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-04-12T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T22:04:02", - "duration": 6958000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T08:30:00", - "duration": 321000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T08:35:21", - "duration": 28800000, - "percent": 0.7, - "rate": 1.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T08:35:21", - "duration": 28800000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-04-12T15:36:19Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T08:35:21", - "duration": 12279000, - "expectedDuration": 28800000, - "percent": 0.7, - "rate": 1.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T08:35:21", - "duration": 28800000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-04-12T15:36:19Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T12:00:00", - "duration": 28200000, - "percent": 0.7, - "rate": 0.45, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T12:00:00", - "duration": 28200000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-04-12T19:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T12:00:00", - "duration": 15906000, - "expectedDuration": 28200000, - "percent": 0.7, - "rate": 0.45, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T12:00:00", - "duration": 28200000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-04-12T19:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T16:25:06", - "duration": 17000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T16:25:23", - "duration": 12600000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T16:25:23", - "duration": 12600000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-04-12T23:26:21Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T16:25:23", - "duration": 5677000, - "expectedDuration": 12600000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T16:25:23", - "duration": 12600000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-04-12T23:26:21Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T18:00:00", - "duration": 12600000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T18:00:00", - "duration": 12600000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-04-13T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T18:00:00", - "duration": 6923000, - "expectedDuration": 12600000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T18:00:00", - "duration": 12600000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-04-13T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T19:55:23", - "duration": 7477000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T22:00:00", - "duration": 5512000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T23:31:52", - "duration": 351000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T23:37:43", - "duration": 562000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T23:47:05", - "duration": 36000000, - "percent": 0.6, - "rate": 0.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T23:47:05", - "duration": 36000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-04-13T06:48:03Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T23:47:05", - "duration": 775000, - "expectedDuration": 36000000, - "percent": 0.6, - "rate": 0.87, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T23:47:05", - "duration": 36000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-04-13T06:48:03Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:00:00", - "duration": 840000, - "percent": 0.6, - "rate": 0.9, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:00:00", - "duration": 840000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-04-13T07:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:00:00", - "duration": 62000, - "expectedDuration": 840000, - "percent": 0.6, - "rate": 0.9, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:00:00", - "duration": 840000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-04-13T07:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:01:02", - "duration": 13000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:01:15", - "duration": 10380000, - "percent": 0.5, - "rate": 0.75, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:01:15", - "duration": 10380000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-04-13T07:02:13Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:01:15", - "duration": 10367000, - "expectedDuration": 10380000, - "percent": 0.5, - "rate": 0.75, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:01:15", - "duration": 10380000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-04-13T07:02:13Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T02:54:02", - "duration": 17000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T02:54:19", - "duration": 27000000, - "percent": 0.35, - "rate": 0.52, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T02:54:19", - "duration": 27000000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-04-13T09:55:17Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T02:54:19", - "duration": 2141000, - "expectedDuration": 27000000, - "percent": 0.35, - "rate": 0.52, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T02:54:19", - "duration": 27000000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-04-13T09:55:17Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T03:30:00", - "duration": 27000000, - "percent": 0.35, - "rate": 0.47, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T03:30:00", - "duration": 27000000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-04-13T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T03:30:00", - "duration": 7200000, - "expectedDuration": 27000000, - "percent": 0.35, - "rate": 0.47, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T03:30:00", - "duration": 27000000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-04-13T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T05:30:00", - "duration": 14700000, - "percent": 0.35, - "rate": 0.54, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T05:30:00", - "duration": 14700000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-04-13T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T05:30:00", - "duration": 5354000, - "expectedDuration": 14700000, - "percent": 0.35, - "rate": 0.54, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T05:30:00", - "duration": 14700000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-04-13T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T06:59:14", - "duration": 5446000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T08:30:00", - "duration": 1684000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T08:58:04", - "duration": 3600000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T08:58:04", - "duration": 3600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-04-13T15:59:02Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T09:58:04", - "duration": 211000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T10:01:35", - "duration": 3600000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T10:01:35", - "duration": 3600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-04-13T17:02:33Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T11:01:35", - "duration": 3505000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T12:00:00", - "duration": 1514000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T12:25:14", - "duration": 12840000, - "percent": 0.55, - "rate": 0.35, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T12:25:14", - "duration": 12840000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-04-13T19:26:12Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T12:25:14", - "duration": 12810000, - "expectedDuration": 12840000, - "percent": 0.55, - "rate": 0.35, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T12:25:14", - "duration": 12840000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-04-13T19:26:12Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T15:58:44", - "duration": 8000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T15:58:52", - "duration": 5400000, - "percent": 1.25, - "rate": 0.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T15:58:52", - "duration": 5400000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-04-13T22:59:50Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T17:28:52", - "duration": 1868000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T18:00:00", - "duration": 4291000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T19:11:31", - "duration": 60000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T19:11:31", - "duration": 60000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-04-14T02:12:29Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T19:11:31", - "duration": 48000, - "expectedDuration": 60000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T19:11:31", - "duration": 60000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-04-14T02:12:29Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T19:12:19", - "duration": 10061000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T00:00:00", - "duration": 2499000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T00:41:39", - "duration": 7200000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T00:41:39", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-04-14T07:42:37Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T02:41:39", - "duration": 2901000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T05:30:00", - "duration": 10759000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T08:29:19", - "duration": 4125000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T09:38:04", - "duration": 8516000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T12:00:00", - "duration": 4493000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T13:14:53", - "duration": 3600000, - "percent": 0.9, - "rate": 0.58, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T13:14:53", - "duration": 3600000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-04-14T20:15:51Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T14:14:53", - "duration": 13507000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T05:30:00", - "duration": 8560000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T07:52:40", - "duration": 8961000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T10:22:01", - "duration": 5879000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T22:00:00", - "duration": 6208000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T23:43:28", - "duration": 7200000, - "percent": 1.1, - "rate": 1.59, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T23:43:28", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-04-18T06:44:26Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T23:43:28", - "duration": 992000, - "expectedDuration": 7200000, - "percent": 1.1, - "rate": 1.59, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T23:43:28", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-04-18T06:44:26Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T00:00:00", - "duration": 7200000, - "percent": 1.1, - "rate": 1.65, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T00:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-04-18T07:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T00:00:00", - "duration": 6208000, - "expectedDuration": 7200000, - "percent": 1.1, - "rate": 1.65, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T00:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-04-18T07:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T01:43:28", - "duration": 6392000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T12:00:00", - "duration": 11187000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T15:06:27", - "duration": 3600000, - "percent": 0.7, - "rate": 0.45, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T15:06:27", - "duration": 3600000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-04-18T22:07:25Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T16:06:27", - "duration": 6813000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T08:30:00", - "duration": 7374000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T10:32:54", - "duration": 790000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T10:46:04", - "duration": 4436000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T05:30:00", - "duration": 10425000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T08:23:45", - "duration": 375000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T12:00:00", - "duration": 10788000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T14:59:48", - "duration": 3678000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T16:01:06", - "duration": 7134000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T12:00:00", - "duration": 9679000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T14:41:19", - "duration": 10800000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T14:41:19", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-04-22T21:42:17Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T17:41:19", - "duration": 1121000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T22:00:00", - "duration": 4227000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T23:10:27", - "duration": 586000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T23:20:13", - "duration": 2387000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T18:00:00", - "duration": 13412000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T21:43:32", - "duration": 200000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T21:46:52", - "duration": 788000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T00:00:00", - "duration": 3746000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:02:26", - "duration": 180000, - "percent": 0.7, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:02:26", - "duration": 180000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-04-26T08:03:24Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:02:26", - "duration": 128000, - "expectedDuration": 180000, - "percent": 0.7, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:02:26", - "duration": 180000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-04-26T08:03:24Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:04:34", - "duration": 11000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:04:45", - "duration": 18000000, - "percent": 0.85, - "rate": 1.31, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:04:45", - "duration": 18000000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-04-26T08:05:43Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:04:45", - "duration": 8715000, - "expectedDuration": 18000000, - "percent": 0.85, - "rate": 1.31, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:04:45", - "duration": 18000000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-04-26T08:05:43Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T03:30:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.19, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T03:30:00", - "duration": 18000000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-04-26T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T03:30:00", - "duration": 7200000, - "expectedDuration": 18000000, - "percent": 0.85, - "rate": 1.19, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T03:30:00", - "duration": 18000000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-04-26T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T05:30:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.36, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T05:30:00", - "duration": 18000000, - "rate": 1.6, - "scheduleName": "basal 3", - "time": "2018-04-26T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T05:30:00", - "duration": 2085000, - "expectedDuration": 18000000, - "percent": 0.85, - "rate": 1.36, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T05:30:00", - "duration": 18000000, - "rate": 1.6, - "scheduleName": "basal 3", - "time": "2018-04-26T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T06:04:45", - "duration": 8715000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T00:00:00", - "duration": 10498000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T02:54:58", - "duration": 21600000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T02:54:58", - "duration": 21600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-04-27T09:55:56Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T02:54:58", - "duration": 2102000, - "expectedDuration": 21600000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T02:54:58", - "duration": 21600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-04-27T09:55:56Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T03:30:00", - "duration": 21600000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T03:30:00", - "duration": 21600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-04-27T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T03:30:00", - "duration": 7200000, - "expectedDuration": 21600000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T03:30:00", - "duration": 21600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-04-27T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T05:30:00", - "duration": 21600000, - "percent": 0.75, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T05:30:00", - "duration": 21600000, - "rate": 1.6, - "scheduleName": "basal 3", - "time": "2018-04-27T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T05:30:00", - "duration": 10800000, - "expectedDuration": 21600000, - "percent": 0.75, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T05:30:00", - "duration": 21600000, - "rate": 1.6, - "scheduleName": "basal 3", - "time": "2018-04-27T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T08:30:00", - "duration": 21600000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T08:30:00", - "duration": 21600000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-04-27T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T08:30:00", - "duration": 1498000, - "expectedDuration": 21600000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T08:30:00", - "duration": 21600000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-04-27T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T08:54:58", - "duration": 11102000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T22:00:00", - "duration": 4513000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T23:15:13", - "duration": 147000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T23:17:40", - "duration": 2540000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T00:00:00", - "duration": 635000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T00:10:35", - "duration": 315000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T00:15:50", - "duration": 11650000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T18:00:00", - "duration": 1631000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T18:27:11", - "duration": 3420000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T18:27:11", - "duration": 3420000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-03T01:28:09Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T18:27:11", - "duration": 3419000, - "expectedDuration": 3420000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T18:27:11", - "duration": 3420000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-03T01:28:09Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T19:24:10", - "duration": 9350000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T05:30:00", - "duration": 3903000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T06:35:03", - "duration": 7200000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T06:35:03", - "duration": 7200000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-05-03T13:36:01Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T06:35:03", - "duration": 6897000, - "expectedDuration": 7200000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T06:35:03", - "duration": 7200000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-05-03T13:36:01Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T08:30:00", - "duration": 7200000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T08:30:00", - "duration": 7200000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-03T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T08:30:00", - "duration": 303000, - "expectedDuration": 7200000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T08:30:00", - "duration": 7200000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-03T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T08:35:03", - "duration": 2092000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T09:09:55", - "duration": 43200000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T09:09:55", - "duration": 43200000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-03T16:10:53Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T09:09:55", - "duration": 10205000, - "expectedDuration": 43200000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T09:09:55", - "duration": 43200000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-03T16:10:53Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T12:00:00", - "duration": 16200000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T12:00:00", - "duration": 16200000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-05-03T19:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T12:00:00", - "duration": 5994000, - "expectedDuration": 16200000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T12:00:00", - "duration": 16200000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-05-03T19:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T13:39:54", - "duration": 221000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T13:43:35", - "duration": 10550000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T16:39:25", - "duration": 21498000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T22:37:43", - "duration": 4937000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T00:00:00", - "duration": 5097000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T01:24:57", - "duration": 30600000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T01:24:57", - "duration": 30600000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-05-04T08:25:55Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T01:24:57", - "duration": 7503000, - "expectedDuration": 30600000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T01:24:57", - "duration": 30600000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-05-04T08:25:55Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T03:30:00", - "duration": 30600000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T03:30:00", - "duration": 30600000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-05-04T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T03:30:00", - "duration": 7200000, - "expectedDuration": 30600000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T03:30:00", - "duration": 30600000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-05-04T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T05:30:00", - "duration": 30600000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T05:30:00", - "duration": 30600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-05-04T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T05:30:00", - "duration": 10800000, - "expectedDuration": 30600000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T05:30:00", - "duration": 30600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-05-04T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T08:30:00", - "duration": 30600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T08:30:00", - "duration": 30600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-05-04T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T08:30:00", - "duration": 5097000, - "expectedDuration": 30600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T08:30:00", - "duration": 30600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-05-04T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T09:54:57", - "duration": 4178000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T11:04:35", - "duration": 41400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T11:04:35", - "duration": 41400000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-04T18:05:33Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T11:04:35", - "duration": 3325000, - "expectedDuration": 41400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T11:04:35", - "duration": 41400000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-04T18:05:33Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T12:00:00", - "duration": 41400000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T12:00:00", - "duration": 41400000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-05-04T19:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T12:00:00", - "duration": 21600000, - "expectedDuration": 41400000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T12:00:00", - "duration": 41400000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-05-04T19:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T18:00:00", - "duration": 41400000, - "percent": 0.75, - "rate": 0.86, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T18:00:00", - "duration": 41400000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-05T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T18:00:00", - "duration": 14400000, - "expectedDuration": 41400000, - "percent": 0.75, - "rate": 0.86, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T18:00:00", - "duration": 41400000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-05T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T22:00:00", - "duration": 41400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T22:00:00", - "duration": 41400000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-05T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T22:00:00", - "duration": 2075000, - "expectedDuration": 41400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T22:00:00", - "duration": 41400000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-05T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T22:34:35", - "duration": 5125000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T00:00:00", - "duration": 4232000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T01:10:32", - "duration": 28800000, - "percent": 0.75, - "rate": 1.12, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T01:10:32", - "duration": 28800000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-05-05T08:11:30Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T01:10:32", - "duration": 8368000, - "expectedDuration": 28800000, - "percent": 0.75, - "rate": 1.12, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T01:10:32", - "duration": 28800000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-05-05T08:11:30Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T03:30:00", - "duration": 28800000, - "percent": 0.75, - "rate": 1.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T03:30:00", - "duration": 28800000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-05-05T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T03:30:00", - "duration": 7200000, - "expectedDuration": 28800000, - "percent": 0.75, - "rate": 1.01, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T03:30:00", - "duration": 28800000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-05-05T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T05:30:00", - "duration": 28800000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T05:30:00", - "duration": 28800000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-05-05T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T05:30:00", - "duration": 10800000, - "expectedDuration": 28800000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T05:30:00", - "duration": 28800000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-05-05T12:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T08:30:00", - "duration": 28800000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T08:30:00", - "duration": 28800000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-05T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T08:30:00", - "duration": 2432000, - "expectedDuration": 28800000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T08:30:00", - "duration": 28800000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-05T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T09:10:32", - "duration": 10168000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T05:30:00", - "duration": 10250000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:20:50", - "duration": 28800000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:20:50", - "duration": 28800000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-05-06T15:21:48Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:20:50", - "duration": 550000, - "expectedDuration": 28800000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:20:50", - "duration": 28800000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-05-06T15:21:48Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:30:00", - "duration": 28800000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:30:00", - "duration": 28800000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-06T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:30:00", - "duration": 12600000, - "expectedDuration": 28800000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:30:00", - "duration": 28800000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-06T15:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T12:00:00", - "duration": 28800000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T12:00:00", - "duration": 28800000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-05-06T19:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T12:00:00", - "duration": 15650000, - "expectedDuration": 28800000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T12:00:00", - "duration": 28800000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-05-06T19:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T16:20:50", - "duration": 5950000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T18:00:00", - "duration": 9910000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T20:45:10", - "duration": 257000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T20:49:27", - "duration": 4233000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T03:30:00", - "duration": 4311000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T04:41:51", - "duration": 18428000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T09:48:59", - "duration": 7861000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T18:00:00", - "duration": 11857000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T21:17:37", - "duration": 10800000, - "percent": 1.15, - "rate": 1.32, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T21:17:37", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-11T04:18:35Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T21:17:37", - "duration": 2543000, - "expectedDuration": 10800000, - "percent": 1.15, - "rate": 1.32, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T21:17:37", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-11T04:18:35Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T22:00:00", - "duration": 5460000, - "percent": 1.15, - "rate": 1.66, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T22:00:00", - "duration": 5460000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-11T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T22:00:00", - "duration": 2891000, - "expectedDuration": 5460000, - "percent": 1.15, - "rate": 1.66, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T22:00:00", - "duration": 5460000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-05-11T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T22:48:11", - "duration": 2421000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T23:28:32", - "duration": 3600000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T23:28:32", - "duration": 3600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-05-11T06:29:30Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T23:28:32", - "duration": 1888000, - "expectedDuration": 3600000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T23:28:32", - "duration": 3600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-05-11T06:29:30Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T00:00:00", - "duration": 3600000, - "percent": 1.25, - "rate": 1.93, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T00:00:00", - "duration": 3600000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-05-11T07:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T00:00:00", - "duration": 1712000, - "expectedDuration": 3600000, - "percent": 1.25, - "rate": 1.93, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T00:00:00", - "duration": 3600000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-05-11T07:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T00:28:32", - "duration": 10888000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T12:00:00", - "duration": 21052000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T17:50:52", - "duration": 10800000, - "percent": 1.25, - "rate": 0.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T17:50:52", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-05-13T00:51:50Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T17:50:52", - "duration": 548000, - "expectedDuration": 10800000, - "percent": 1.25, - "rate": 0.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T17:50:52", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-05-13T00:51:50Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T18:00:00", - "duration": 10800000, - "percent": 1.25, - "rate": 1.43, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T18:00:00", - "duration": 10800000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-05-13T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T18:00:00", - "duration": 10252000, - "expectedDuration": 10800000, - "percent": 1.25, - "rate": 1.43, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T18:00:00", - "duration": 10800000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-05-13T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T20:50:52", - "duration": 4148000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T05:30:00", - "duration": 1821000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T06:00:21", - "duration": 217000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T06:03:58", - "duration": 8762000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T18:00:00", - "duration": 2689000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T18:44:49", - "duration": 3986000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T19:51:15", - "duration": 7725000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T18:00:00", - "duration": 8609000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T20:23:29", - "duration": 9000000, - "percent": 1.5, - "rate": 1.72, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T20:23:29", - "duration": 9000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-16T03:24:27Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T20:23:29", - "duration": 5791000, - "expectedDuration": 9000000, - "percent": 1.5, - "rate": 1.72, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T20:23:29", - "duration": 9000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-16T03:24:27Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T22:00:00", - "duration": 7140000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T22:00:00", - "duration": 7140000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-05-16T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T22:00:00", - "duration": 1292000, - "expectedDuration": 7140000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T22:00:00", - "duration": 7140000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-05-16T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T22:21:32", - "duration": 5908000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T12:00:00", - "duration": 16133000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T16:28:53", - "duration": 113000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T16:30:46", - "duration": 5354000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T12:00:00", - "duration": 19563000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T17:26:03", - "duration": 368000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T17:32:11", - "duration": 1669000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T22:00:00", - "duration": 1859000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T22:30:59", - "duration": 3600000, - "percent": 1.95, - "rate": 2.82, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T22:30:59", - "duration": 3600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-05-23T05:31:57Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T23:30:59", - "duration": 1741000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T08:30:00", - "duration": 8897000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T10:58:17", - "duration": 1755000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T11:27:32", - "duration": 1948000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T12:00:00", - "duration": 19655000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T17:27:35", - "duration": 375000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T17:33:50", - "duration": 1570000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T18:00:00", - "duration": 13374000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T21:42:54", - "duration": 10800000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T21:42:54", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-24T04:43:52Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T21:42:54", - "duration": 1026000, - "expectedDuration": 10800000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T21:42:54", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-05-24T04:43:52Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T22:00:00", - "duration": 10800000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T22:00:00", - "duration": 10800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-05-24T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T22:00:00", - "duration": 7200000, - "expectedDuration": 10800000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T22:00:00", - "duration": 10800000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-05-24T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T00:00:00", - "duration": 10800000, - "percent": 1.4, - "rate": 2.1, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T00:00:00", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-05-24T07:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T00:00:00", - "duration": 2574000, - "expectedDuration": 10800000, - "percent": 1.4, - "rate": 2.1, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T00:00:00", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-05-24T07:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T00:42:54", - "duration": 10026000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T08:30:00", - "duration": 11426000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T11:40:26", - "duration": 7949000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T13:52:55", - "duration": 14825000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T08:30:00", - "duration": 2522000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T09:12:02", - "duration": 14514000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T13:13:56", - "duration": 17164000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T18:00:00", - "duration": 14339000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T21:58:59", - "duration": 1800000, - "percent": 0.09999999999999998, - "rate": 0.11, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T21:58:59", - "duration": 1800000, - "rate": 1.1, - "scheduleName": "basal 3", - "time": "2018-05-30T04:59:57Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T21:58:59", - "duration": 61000, - "expectedDuration": 1800000, - "percent": 0.09999999999999998, - "rate": 0.11, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T21:58:59", - "duration": 1800000, - "rate": 1.1, - "scheduleName": "basal 3", - "time": "2018-05-30T04:59:57Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T22:00:00", - "duration": 1800000, - "percent": 0.09999999999999998, - "rate": 0.14, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T22:00:00", - "duration": 1800000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-05-30T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T22:00:00", - "duration": 1739000, - "expectedDuration": 1800000, - "percent": 0.09999999999999998, - "rate": 0.14, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T22:00:00", - "duration": 1800000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-05-30T05:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T22:28:59", - "duration": 5461000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T12:00:00", - "duration": 20380000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T17:39:40", - "duration": 3600000, - "percent": 0.65, - "rate": 0.42, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T17:39:40", - "duration": 3600000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-05-31T00:40:38Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T17:39:40", - "duration": 1220000, - "expectedDuration": 3600000, - "percent": 0.65, - "rate": 0.42, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T17:39:40", - "duration": 3600000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-05-31T00:40:38Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T18:00:00", - "duration": 3600000, - "percent": 0.65, - "rate": 0.74, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T18:00:00", - "duration": 3600000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-05-31T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T18:00:00", - "duration": 2380000, - "expectedDuration": 3600000, - "percent": 0.65, - "rate": 0.74, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T18:00:00", - "duration": 3600000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-05-31T01:00:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T18:39:40", - "duration": 12020000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T22:00:00", - "duration": 1941000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T22:32:21", - "duration": 332000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T22:37:53", - "duration": 4927000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T00:00:00", - "duration": 7844000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T02:10:44", - "duration": 5400000, - "percent": 0.6, - "rate": 0.9, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T02:10:44", - "duration": 5400000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-06-01T09:11:42Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T02:10:44", - "duration": 4756000, - "expectedDuration": 5400000, - "percent": 0.6, - "rate": 0.9, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T02:10:44", - "duration": 5400000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-06-01T09:11:42Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T03:30:00", - "duration": 5400000, - "percent": 0.6, - "rate": 0.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T03:30:00", - "duration": 5400000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-06-01T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T03:30:00", - "duration": 644000, - "expectedDuration": 5400000, - "percent": 0.6, - "rate": 0.81, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T03:30:00", - "duration": 5400000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-06-01T10:30:58Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T03:40:44", - "duration": 6556000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T22:00:00", - "duration": 89000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T22:01:29", - "duration": 427000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T22:08:36", - "duration": 6684000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T12:00:00", - "duration": 6521000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:48:41", - "duration": 180000, - "percent": 0.6, - "rate": 0.39, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:48:41", - "duration": 180000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-06-03T20:49:39Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:48:41", - "duration": 154000, - "expectedDuration": 180000, - "percent": 0.6, - "rate": 0.39, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:48:41", - "duration": 180000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-06-03T20:49:39Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:51:15", - "duration": 329000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:56:44", - "duration": 5400000, - "percent": 1.2, - "rate": 0.78, - "suppressed": { - "conversionOffset": -3658000, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:56:44", - "duration": 5400000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-06-03T20:57:42Z", - "timezoneOffset": -360, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T15:26:44", - "duration": 9196000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T00:00:00", - "duration": 2718000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T00:45:18", - "duration": 410000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T00:52:08", - "duration": 9472000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T18:00:00", - "duration": 9098000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T20:31:38", - "duration": 238000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T20:35:36", - "duration": 5064000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T12:00:00", - "duration": 6090000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T13:41:30", - "duration": 277000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T13:46:07", - "duration": 8525000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-07T15:08:12", - "duration": 13000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T16:08:25", - "duration": 10295000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-07T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T12:00:00", - "duration": 537000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T12:08:57", - "duration": 190000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T12:12:07", - "duration": 20873000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T12:00:00", - "duration": 3798000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T13:03:18", - "duration": 482000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T14:12:18", - "duration": 13662000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T03:30:00", - "duration": 3971000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T04:36:11", - "duration": 250000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T04:40:21", - "duration": 2979000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T22:00:00", - "duration": 3091000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T22:51:31", - "duration": 1929000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T23:23:40", - "duration": 2180000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T12:00:00", - "duration": 2125000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T12:35:25", - "duration": 1737000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T13:04:22", - "duration": 17738000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T00:00:00", - "duration": 1723000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T00:28:43", - "duration": 27000000, - "percent": 0.65, - "rate": 0.97, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T00:28:43", - "duration": 27000000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-06-15T07:28:43Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T00:28:43", - "duration": 10877000, - "expectedDuration": 27000000, - "percent": 0.65, - "rate": 0.97, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T00:28:43", - "duration": 27000000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-06-15T07:28:43Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T03:30:00", - "duration": 27000000, - "percent": 0.65, - "rate": 0.87, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T03:30:00", - "duration": 27000000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-06-15T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T03:30:00", - "duration": 7200000, - "expectedDuration": 27000000, - "percent": 0.65, - "rate": 0.87, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T03:30:00", - "duration": 27000000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-06-15T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T05:30:00", - "duration": 27000000, - "percent": 0.65, - "rate": 1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T05:30:00", - "duration": 27000000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-06-15T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T05:30:00", - "duration": 8923000, - "expectedDuration": 27000000, - "percent": 0.65, - "rate": 1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T05:30:00", - "duration": 27000000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-06-15T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T07:58:43", - "duration": 1877000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T12:00:00", - "duration": 11186000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T15:06:26", - "duration": 10709000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T18:04:55", - "duration": 14105000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T08:30:00", - "duration": 7555000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T10:35:55", - "duration": 27000000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T10:35:55", - "duration": 27000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-06-18T17:35:55Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T10:35:55", - "duration": 5045000, - "expectedDuration": 27000000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T10:35:55", - "duration": 27000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-06-18T17:35:55Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T12:00:00", - "duration": 27000000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T12:00:00", - "duration": 27000000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-06-18T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T12:00:00", - "duration": 21600000, - "expectedDuration": 27000000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T12:00:00", - "duration": 27000000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-06-18T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T18:00:00", - "duration": 27000000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T18:00:00", - "duration": 27000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-06-19T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T18:00:00", - "duration": 354000, - "expectedDuration": 27000000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T18:00:00", - "duration": 27000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-06-19T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T18:05:54", - "duration": 6111000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T19:47:45", - "duration": 18000000, - "percent": 0.85, - "rate": 0.97, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T19:47:45", - "duration": 18000000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-06-19T02:47:45Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T19:47:45", - "duration": 7935000, - "expectedDuration": 18000000, - "percent": 0.85, - "rate": 0.97, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T19:47:45", - "duration": 18000000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-06-19T02:47:45Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T22:00:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.23, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T22:00:00", - "duration": 18000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-06-19T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T22:00:00", - "duration": 7200000, - "expectedDuration": 18000000, - "percent": 0.85, - "rate": 1.23, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T22:00:00", - "duration": 18000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-06-19T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T00:00:00", - "duration": 17880000, - "percent": 0.85, - "rate": 1.27, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T00:00:00", - "duration": 17880000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-06-19T07:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T00:00:00", - "duration": 2696000, - "expectedDuration": 17880000, - "percent": 0.85, - "rate": 1.27, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T00:00:00", - "duration": 17880000, - "rate": 1.49, - "scheduleName": "basal 3", - "time": "2018-06-19T07:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T00:44:56", - "duration": 112000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T00:46:48", - "duration": 9792000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T18:00:00", - "duration": 10769000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T20:59:29", - "duration": 3631000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T08:30:00", - "duration": 10621000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T11:27:01", - "duration": 25200000, - "percent": 0.8, - "rate": 1.12, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T11:27:01", - "duration": 25200000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-06-21T18:27:01Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T11:27:01", - "duration": 1979000, - "expectedDuration": 25200000, - "percent": 0.8, - "rate": 1.12, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T11:27:01", - "duration": 25200000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-06-21T18:27:01Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T12:00:00", - "duration": 14160000, - "percent": 0.8, - "rate": 0.48, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T12:00:00", - "duration": 14160000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-06-21T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T12:00:00", - "duration": 12135000, - "expectedDuration": 14160000, - "percent": 0.8, - "rate": 0.48, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T12:00:00", - "duration": 14160000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-06-21T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T15:22:15", - "duration": 52000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T18:23:07", - "duration": 13013000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T22:00:00", - "duration": 6238000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T23:43:58", - "duration": 870000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T23:58:28", - "duration": 92000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T00:00:00", - "duration": 9249000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T02:34:09", - "duration": 9000000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T02:34:09", - "duration": 9000000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-06-24T06:34:09Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T02:34:09", - "duration": 3351000, - "expectedDuration": 9000000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T02:34:09", - "duration": 9000000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-06-24T06:34:09Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T03:30:00", - "duration": 9000000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T03:30:00", - "duration": 9000000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-06-24T07:30:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T03:30:00", - "duration": 5649000, - "expectedDuration": 9000000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T03:30:00", - "duration": 9000000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-06-24T07:30:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T05:04:09", - "duration": 1551000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T08:30:00", - "duration": 6845000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T10:24:05", - "duration": 10800000, - "percent": 1.35, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T10:24:05", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-06-24T14:24:05Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T10:24:05", - "duration": 5755000, - "expectedDuration": 10800000, - "percent": 1.35, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T10:24:05", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-06-24T14:24:05Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T12:00:00", - "duration": 10800000, - "percent": 1.35, - "rate": 0.81, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T12:00:00", - "duration": 10800000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-06-24T16:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T12:00:00", - "duration": 5045000, - "expectedDuration": 10800000, - "percent": 1.35, - "rate": 0.81, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T12:00:00", - "duration": 10800000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-06-24T16:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T13:24:05", - "duration": 16555000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T05:30:00", - "duration": 8167000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T07:46:07", - "duration": 5319000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T09:14:46", - "duration": 9914000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T22:00:00", - "duration": 2939000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T22:48:59", - "duration": 3600000, - "percent": 0.85, - "rate": 1.19, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T22:48:59", - "duration": 3600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-06-26T02:48:59Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T23:48:59", - "duration": 661000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T00:00:00", - "duration": 10930000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T03:02:10", - "duration": 56000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T00:03:06", - "duration": 12414000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T12:00:00", - "duration": 16156000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T16:29:16", - "duration": 5400000, - "percent": 1.4, - "rate": 0.84, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T16:29:16", - "duration": 5400000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-06-27T23:29:16Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T17:59:16", - "duration": 44000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T12:00:00", - "duration": 7901000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T14:11:41", - "duration": 1866000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T14:42:47", - "duration": 11833000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T08:30:00", - "duration": 7554000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T10:35:54", - "duration": 27000000, - "percent": 0.85, - "rate": 1.19, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T10:35:54", - "duration": 27000000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-06-29T17:35:54Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T10:35:54", - "duration": 5046000, - "expectedDuration": 27000000, - "percent": 0.85, - "rate": 1.19, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T10:35:54", - "duration": 27000000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-06-29T17:35:54Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T12:00:00", - "duration": 27000000, - "percent": 0.85, - "rate": 0.51, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T12:00:00", - "duration": 27000000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-06-29T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T12:00:00", - "duration": 21600000, - "expectedDuration": 27000000, - "percent": 0.85, - "rate": 0.51, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T12:00:00", - "duration": 27000000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-06-29T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T18:00:00", - "duration": 27000000, - "percent": 0.85, - "rate": 0.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T18:00:00", - "duration": 27000000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-06-30T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T18:00:00", - "duration": 354000, - "expectedDuration": 27000000, - "percent": 0.85, - "rate": 0.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T18:00:00", - "duration": 27000000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-06-30T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T18:05:54", - "duration": 14046000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T22:00:00", - "duration": 5283000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T23:28:03", - "duration": 3855000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T00:32:18", - "duration": 10662000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T18:00:00", - "duration": 6951000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T19:55:51", - "duration": 7449000, - "rate": 1, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T22:00:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T05:30:00", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T08:30:00", - "duration": 10564000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T11:26:04", - "duration": 139000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T11:28:23", - "duration": 1897000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T00:00:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T03:30:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T00:00:00", - "duration": 11060000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:04:20", - "duration": 21600000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:04:20", - "duration": 21600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-07-03T10:04:20Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:04:20", - "duration": 1540000, - "expectedDuration": 21600000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:04:20", - "duration": 21600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-07-03T10:04:20Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:30:00", - "duration": 21600000, - "percent": 0.75, - "rate": 0.93, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:30:00", - "duration": 21600000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-07-03T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:30:00", - "duration": 7200000, - "expectedDuration": 21600000, - "percent": 0.75, - "rate": 0.93, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:30:00", - "duration": 21600000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-07-03T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T05:30:00", - "duration": 19560000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T05:30:00", - "duration": 19560000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-07-03T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T05:30:00", - "duration": 10631000, - "expectedDuration": 19560000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T05:30:00", - "duration": 19560000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-07-03T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T08:27:11", - "duration": 10538000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T11:22:49", - "duration": 2231000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T00:00:00", - "duration": 10459000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T02:54:19", - "duration": 7200000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T02:54:19", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-07-04T09:54:19Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T02:54:19", - "duration": 2141000, - "expectedDuration": 7200000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T02:54:19", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-07-04T09:54:19Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T03:30:00", - "duration": 7200000, - "percent": 0.75, - "rate": 0.93, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T03:30:00", - "duration": 7200000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-07-04T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T03:30:00", - "duration": 5059000, - "expectedDuration": 7200000, - "percent": 0.75, - "rate": 0.93, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T03:30:00", - "duration": 7200000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-07-04T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T04:54:19", - "duration": 2141000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T00:00:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T03:30:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T00:00:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T03:30:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T18:00:00", - "duration": 4501000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T19:15:01", - "duration": 442000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T19:22:23", - "duration": 9457000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T00:00:00", - "duration": 9207000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T02:33:27", - "duration": 3600000, - "percent": 1.35, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T02:33:27", - "duration": 3600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-07-07T09:33:27Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T02:33:27", - "duration": 3393000, - "expectedDuration": 3600000, - "percent": 1.35, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T02:33:27", - "duration": 3600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-07-07T09:33:27Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T03:30:00", - "duration": 3600000, - "percent": 1.35, - "rate": 1.68, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T03:30:00", - "duration": 3600000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-07-07T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T03:30:00", - "duration": 207000, - "expectedDuration": 3600000, - "percent": 1.35, - "rate": 1.68, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T03:30:00", - "duration": 3600000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-07-07T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T03:33:27", - "duration": 6993000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T00:00:00", - "duration": 7931000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T02:12:11", - "duration": 1802000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T02:42:13", - "duration": 2867000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T00:00:00", - "duration": 1644000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T00:27:24", - "duration": 387000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T00:33:51", - "duration": 10569000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T05:30:00", - "duration": 11850000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T08:47:30", - "duration": 7734000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T10:56:24", - "duration": 3816000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T12:00:00", - "duration": 11503000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T15:11:43", - "duration": 238000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T15:15:41", - "duration": 9859000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T00:00:00", - "duration": 11695000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:14:55", - "duration": 18000000, - "percent": 0.85, - "rate": 1.1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:14:55", - "duration": 18000000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-07-15T10:14:55Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:14:55", - "duration": 905000, - "expectedDuration": 18000000, - "percent": 0.85, - "rate": 1.1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:14:55", - "duration": 18000000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-07-15T10:14:55Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:30:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.02, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:30:00", - "duration": 18000000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-07-15T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:30:00", - "duration": 7200000, - "expectedDuration": 18000000, - "percent": 0.85, - "rate": 1.02, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:30:00", - "duration": 18000000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-07-15T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T05:30:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T05:30:00", - "duration": 18000000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-07-15T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T05:30:00", - "duration": 9895000, - "expectedDuration": 18000000, - "percent": 0.85, - "rate": 1.1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T05:30:00", - "duration": 18000000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-07-15T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T08:14:55", - "duration": 905000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T08:30:00", - "duration": 4149000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T09:39:09", - "duration": 6405000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T11:25:54", - "duration": 2046000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T12:00:00", - "duration": 10914000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T15:01:54", - "duration": 3600000, - "percent": 1.25, - "rate": 0.56, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T15:01:54", - "duration": 3600000, - "rate": 0.45, - "scheduleName": "basal 3", - "time": "2018-07-17T22:01:54Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T16:01:54", - "duration": 7086000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T12:00:00", - "duration": 14774000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T16:06:14", - "duration": 789000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T16:19:23", - "duration": 6037000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T18:00:00", - "duration": 5447000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T19:30:47", - "duration": 10800000, - "percent": 1.15, - "rate": 1.03, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T19:30:47", - "duration": 10800000, - "rate": 0.9, - "scheduleName": "basal 3", - "time": "2018-07-20T02:30:47Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T19:30:47", - "duration": 8953000, - "expectedDuration": 10800000, - "percent": 1.15, - "rate": 1.03, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T19:30:47", - "duration": 10800000, - "rate": 0.9, - "scheduleName": "basal 3", - "time": "2018-07-20T02:30:47Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T22:00:00", - "duration": 10800000, - "percent": 1.15, - "rate": 1.43, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T22:00:00", - "duration": 10800000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-07-20T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T22:00:00", - "duration": 1847000, - "expectedDuration": 10800000, - "percent": 1.15, - "rate": 1.43, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T22:00:00", - "duration": 10800000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-07-20T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T22:30:47", - "duration": 5353000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T00:00:00", - "duration": 7351000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T02:02:31", - "duration": 5400000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T02:02:31", - "duration": 5400000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-07-22T09:02:31Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T02:02:31", - "duration": 5249000, - "expectedDuration": 5400000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T02:02:31", - "duration": 5400000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-07-22T09:02:31Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T03:30:00", - "duration": 5400000, - "percent": 0.8, - "rate": 0.96, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T03:30:00", - "duration": 5400000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-07-22T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T03:30:00", - "duration": 151000, - "expectedDuration": 5400000, - "percent": 0.8, - "rate": 0.96, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T03:30:00", - "duration": 5400000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-07-22T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T03:32:31", - "duration": 7049000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T00:00:00", - "duration": 829000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T00:13:49", - "duration": 2232000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T00:51:01", - "duration": 9539000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T08:30:00", - "duration": 1596000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T08:56:36", - "duration": 882000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T09:11:18", - "duration": 10122000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T18:00:00", - "duration": 124000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T18:02:04", - "duration": 5400000, - "percent": 0.85, - "rate": 0.76, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T18:02:04", - "duration": 5400000, - "rate": 0.89, - "scheduleName": "basal 3", - "time": "2018-07-27T01:02:04Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T19:32:04", - "duration": 8876000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T00:00:00", - "duration": 860000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T00:14:20", - "duration": 2644000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T00:58:24", - "duration": 9096000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T18:00:00", - "duration": 1335000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T18:22:15", - "duration": 5400000, - "percent": 0.4, - "rate": 0.36, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T18:22:15", - "duration": 5400000, - "rate": 0.9, - "scheduleName": "basal 3", - "time": "2018-07-31T01:22:15Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T19:52:15", - "duration": 7665000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T00:00:00", - "duration": 7906000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T02:11:46", - "duration": 21445000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T08:09:11", - "duration": 1249000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T00:00:00", - "duration": 6044000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T01:40:44", - "duration": 5880000, - "percent": 0.85, - "rate": 1.1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T01:40:44", - "duration": 5880000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-08-03T08:40:44Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T01:40:44", - "duration": 5867000, - "expectedDuration": 5880000, - "percent": 0.85, - "rate": 1.1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T01:40:44", - "duration": 5880000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-08-03T08:40:44Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:18:31", - "duration": 9000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:18:40", - "duration": 7200000, - "percent": 0.7, - "rate": 0.91, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:18:40", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-08-03T10:18:40Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:18:40", - "duration": 680000, - "expectedDuration": 7200000, - "percent": 0.7, - "rate": 0.91, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:18:40", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-08-03T10:18:40Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:30:00", - "duration": 7200000, - "percent": 0.7, - "rate": 0.84, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-08-03T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:30:00", - "duration": 6520000, - "expectedDuration": 7200000, - "percent": 0.7, - "rate": 0.84, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-08-03T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T05:18:40", - "duration": 680000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T12:00:00", - "duration": 8453000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T14:20:53", - "duration": 326000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T14:26:19", - "duration": 12821000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T12:00:00", - "duration": 18803000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T17:13:23", - "duration": 7200000, - "percent": 1.25, - "rate": 0.56, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T17:13:23", - "duration": 7200000, - "rate": 0.45, - "scheduleName": "basal 3", - "time": "2018-08-06T00:13:23Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T17:13:23", - "duration": 2797000, - "expectedDuration": 7200000, - "percent": 1.25, - "rate": 0.56, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T17:13:23", - "duration": 7200000, - "rate": 0.45, - "scheduleName": "basal 3", - "time": "2018-08-06T00:13:23Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T18:00:00", - "duration": 7200000, - "percent": 1.25, - "rate": 1.12, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T18:00:00", - "duration": 7200000, - "rate": 0.9, - "scheduleName": "basal 3", - "time": "2018-08-06T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T18:00:00", - "duration": 4403000, - "expectedDuration": 7200000, - "percent": 1.25, - "rate": 1.12, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T18:00:00", - "duration": 7200000, - "rate": 0.9, - "scheduleName": "basal 3", - "time": "2018-08-06T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T19:13:23", - "duration": 9106000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T21:45:09", - "duration": 251000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T21:49:20", - "duration": 640000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T05:30:00", - "duration": 9183000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T08:03:03", - "duration": 1617000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T03:30:00", - "duration": 5472000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T05:01:12", - "duration": 180000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T05:04:12", - "duration": 1548000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T18:00:00", - "duration": 13178000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T21:39:38", - "duration": 3600000, - "percent": 1.15, - "rate": 1.2, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T21:39:38", - "duration": 3600000, - "rate": 1.04, - "scheduleName": "basal 3", - "time": "2018-08-12T04:39:38Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T21:39:38", - "duration": 1222000, - "expectedDuration": 3600000, - "percent": 1.15, - "rate": 1.2, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T21:39:38", - "duration": 3600000, - "rate": 1.04, - "scheduleName": "basal 3", - "time": "2018-08-12T04:39:38Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T22:00:00", - "duration": 3600000, - "percent": 1.15, - "rate": 1.61, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T22:00:00", - "duration": 3600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-08-12T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T22:00:00", - "duration": 2378000, - "expectedDuration": 3600000, - "percent": 1.15, - "rate": 1.61, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T22:00:00", - "duration": 3600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-08-12T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T22:39:38", - "duration": 4822000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T12:00:00", - "duration": 4236000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T13:10:36", - "duration": 3620000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T14:10:56", - "duration": 3631000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T15:11:27", - "duration": 600000, - "percent": 0.8, - "rate": 0.48, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T15:11:27", - "duration": 600000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-08-12T22:11:27Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T15:11:27", - "duration": 588000, - "expectedDuration": 600000, - "percent": 0.8, - "rate": 0.48, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T15:11:27", - "duration": 600000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-08-12T22:11:27Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T15:21:15", - "duration": 7934000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T17:33:29", - "duration": 1591000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T00:00:00", - "duration": 8499000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T02:21:39", - "duration": 16200000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T02:21:39", - "duration": 16200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-08-14T09:21:39Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T02:21:39", - "duration": 4101000, - "expectedDuration": 16200000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T02:21:39", - "duration": 16200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-08-14T09:21:39Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T03:30:00", - "duration": 16200000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T03:30:00", - "duration": 16200000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-08-14T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T03:30:00", - "duration": 7200000, - "expectedDuration": 16200000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T03:30:00", - "duration": 16200000, - "rate": 1.35, - "scheduleName": "basal 3", - "time": "2018-08-14T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T05:30:00", - "duration": 16200000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T05:30:00", - "duration": 16200000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-08-14T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T05:30:00", - "duration": 4899000, - "expectedDuration": 16200000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T05:30:00", - "duration": 16200000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-08-14T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T06:51:39", - "duration": 5901000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T18:00:00", - "duration": 3812000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T19:03:32", - "duration": 6060000, - "percent": 0.75, - "rate": 0.78, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T19:03:32", - "duration": 6060000, - "rate": 1.04, - "scheduleName": "basal 3", - "time": "2018-08-15T02:03:32Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T19:03:32", - "duration": 6031000, - "expectedDuration": 6060000, - "percent": 0.75, - "rate": 0.78, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T19:03:32", - "duration": 6060000, - "rate": 1.04, - "scheduleName": "basal 3", - "time": "2018-08-15T02:03:32Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T20:44:03", - "duration": 9000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T20:44:12", - "duration": 5400000, - "percent": 0.65, - "rate": 0.68, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T20:44:12", - "duration": 5400000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-08-15T03:44:12Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T20:44:12", - "duration": 4548000, - "expectedDuration": 5400000, - "percent": 0.65, - "rate": 0.68, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T20:44:12", - "duration": 5400000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-08-15T03:44:12Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T22:00:00", - "duration": 5400000, - "percent": 0.65, - "rate": 0.91, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T22:00:00", - "duration": 5400000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-08-15T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T22:00:00", - "duration": 852000, - "expectedDuration": 5400000, - "percent": 0.65, - "rate": 0.91, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T22:00:00", - "duration": 5400000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-08-15T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T22:14:12", - "duration": 6348000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T08:30:00", - "duration": 7596000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T10:36:36", - "duration": 5004000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T18:00:00", - "duration": 57000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T18:00:57", - "duration": 10800000, - "percent": 0.19999999999999996, - "rate": 0.18, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T18:00:57", - "duration": 10800000, - "rate": 0.9, - "scheduleName": "basal 3", - "time": "2018-08-16T01:00:57Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T21:00:57", - "duration": 2953000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T21:50:10", - "duration": 240000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T21:54:10", - "duration": 350000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T05:30:00", - "duration": 1539000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T05:55:39", - "duration": 255000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T05:59:54", - "duration": 9006000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T12:00:00", - "duration": 19916000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T17:31:56", - "duration": 9000000, - "percent": 0.6, - "rate": 0.27, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T17:31:56", - "duration": 9000000, - "rate": 0.45, - "scheduleName": "basal 3", - "time": "2018-08-21T00:31:56Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T17:31:56", - "duration": 1684000, - "expectedDuration": 9000000, - "percent": 0.6, - "rate": 0.27, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T17:31:56", - "duration": 9000000, - "rate": 0.45, - "scheduleName": "basal 3", - "time": "2018-08-21T00:31:56Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T18:00:00", - "duration": 9000000, - "percent": 0.6, - "rate": 0.54, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T18:00:00", - "duration": 9000000, - "rate": 0.9, - "scheduleName": "basal 3", - "time": "2018-08-21T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T18:00:00", - "duration": 7316000, - "expectedDuration": 9000000, - "percent": 0.6, - "rate": 0.54, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T18:00:00", - "duration": 9000000, - "rate": 0.9, - "scheduleName": "basal 3", - "time": "2018-08-21T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T20:01:56", - "duration": 7084000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T12:00:00", - "duration": 12721000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T15:32:01", - "duration": 1800000, - "percent": 0.7, - "rate": 0.31, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T15:32:01", - "duration": 1800000, - "rate": 0.44, - "scheduleName": "basal 3", - "time": "2018-08-21T22:32:01Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T16:02:01", - "duration": 7079000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T12:00:00", - "duration": 6854000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T13:54:14", - "duration": 473000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T14:02:07", - "duration": 14273000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T00:00:00", - "duration": 11831000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:17:11", - "duration": 25200000, - "percent": 0.75, - "rate": 0.97, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:17:11", - "duration": 25200000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-08-23T10:17:11Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:17:11", - "duration": 769000, - "expectedDuration": 25200000, - "percent": 0.75, - "rate": 0.97, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:17:11", - "duration": 25200000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-08-23T10:17:11Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:30:00", - "duration": 25200000, - "percent": 0.75, - "rate": 0.9, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:30:00", - "duration": 25200000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-08-23T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:30:00", - "duration": 7200000, - "expectedDuration": 25200000, - "percent": 0.75, - "rate": 0.9, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:30:00", - "duration": 25200000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-08-23T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T05:30:00", - "duration": 25200000, - "percent": 0.75, - "rate": 0.97, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T05:30:00", - "duration": 25200000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-08-23T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T05:30:00", - "duration": 10800000, - "expectedDuration": 25200000, - "percent": 0.75, - "rate": 0.97, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T05:30:00", - "duration": 25200000, - "rate": 1.29, - "scheduleName": "basal 3", - "time": "2018-08-23T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T08:30:00", - "duration": 25200000, - "percent": 0.75, - "rate": 0.93, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T08:30:00", - "duration": 25200000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-08-23T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T08:30:00", - "duration": 6431000, - "expectedDuration": 25200000, - "percent": 0.75, - "rate": 0.93, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T08:30:00", - "duration": 25200000, - "rate": 1.24, - "scheduleName": "basal 3", - "time": "2018-08-23T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T10:17:11", - "duration": 6169000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T00:00:00", - "duration": 7034000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T01:57:14", - "duration": 25200000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T01:57:14", - "duration": 25200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-08-24T08:57:14Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T01:57:14", - "duration": 5566000, - "expectedDuration": 25200000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T01:57:14", - "duration": 25200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-08-24T08:57:14Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T03:30:00", - "duration": 25200000, - "percent": 0.8, - "rate": 0.96, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T03:30:00", - "duration": 25200000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-08-24T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T03:30:00", - "duration": 7200000, - "expectedDuration": 25200000, - "percent": 0.8, - "rate": 0.96, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T03:30:00", - "duration": 25200000, - "rate": 1.2, - "scheduleName": "basal 3", - "time": "2018-08-24T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T05:30:00", - "duration": 25200000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T05:30:00", - "duration": 25200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-08-24T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T05:30:00", - "duration": 10800000, - "expectedDuration": 25200000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T05:30:00", - "duration": 25200000, - "rate": 1.3, - "scheduleName": "basal 3", - "time": "2018-08-24T12:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T08:30:00", - "duration": 25200000, - "percent": 0.8, - "rate": 1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T08:30:00", - "duration": 25200000, - "rate": 1.25, - "scheduleName": "basal 3", - "time": "2018-08-24T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T08:30:00", - "duration": 1634000, - "expectedDuration": 25200000, - "percent": 0.8, - "rate": 1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T08:30:00", - "duration": 25200000, - "rate": 1.25, - "scheduleName": "basal 3", - "time": "2018-08-24T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T08:57:14", - "duration": 10966000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T12:00:00", - "duration": 8532000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T14:22:12", - "duration": 7200000, - "percent": 0.30000000000000004, - "rate": 0.13, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T14:22:12", - "duration": 7200000, - "rate": 0.43, - "scheduleName": "basal 3", - "time": "2018-08-24T21:22:12Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T16:22:12", - "duration": 5868000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T18:00:00", - "duration": 14095000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T21:54:55", - "duration": 280000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T21:59:35", - "duration": 25000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T03:30:00", - "duration": 6075000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T05:11:15", - "duration": 397000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T05:17:52", - "duration": 728000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T12:00:00", - "duration": 4392000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T13:13:12", - "duration": 17592000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T18:06:24", - "duration": 14016000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T08:30:00", - "duration": 9169000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T11:02:49", - "duration": 3431000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T05:30:00", - "duration": 4177000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T06:39:37", - "duration": 10025000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T09:26:42", - "duration": 9198000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T12:00:00", - "duration": 19217000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T17:20:17", - "duration": 6688000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T19:11:45", - "duration": 10095000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T00:00:00", - "duration": 1827000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T00:30:27", - "duration": 1374000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T00:53:21", - "duration": 9399000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T08:30:00", - "duration": 2264000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T09:07:44", - "duration": 7415000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T11:11:19", - "duration": 1593000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T11:37:52", - "duration": 5400000, - "percent": 1.35, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T11:37:52", - "duration": 5400000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-09-14T18:37:52Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T11:37:52", - "duration": 1328000, - "expectedDuration": 5400000, - "percent": 1.35, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T11:37:52", - "duration": 5400000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-09-14T18:37:52Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T12:00:00", - "duration": 5400000, - "percent": 1.35, - "rate": 0.81, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T12:00:00", - "duration": 5400000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-14T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T12:00:00", - "duration": 4072000, - "expectedDuration": 5400000, - "percent": 1.35, - "rate": 0.81, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T12:00:00", - "duration": 5400000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-14T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T13:07:52", - "duration": 17528000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T12:00:00", - "duration": 142000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T12:02:22", - "duration": 3600000, - "percent": 0.7, - "rate": 0.42, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T12:02:22", - "duration": 3600000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-15T19:02:22Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T13:02:22", - "duration": 17858000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T08:30:00", - "duration": 5863000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T10:07:43", - "duration": 5400000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T10:07:43", - "duration": 5400000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-09-16T17:07:43Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T11:37:43", - "duration": 1337000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T18:00:00", - "duration": 4181000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T19:09:41", - "duration": 3495000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T20:07:56", - "duration": 6724000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T12:00:00", - "duration": 5103000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T13:25:03", - "duration": 76000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T13:26:19", - "duration": 16421000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T18:00:00", - "duration": 13638000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T21:47:18", - "duration": 533000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T21:56:11", - "duration": 229000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T18:00:00", - "duration": 2999000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T18:49:59", - "duration": 3600000, - "percent": 1.45, - "rate": 1.52, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T18:49:59", - "duration": 3600000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-09-21T01:49:59Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T19:49:59", - "duration": 7801000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T00:00:00", - "duration": 2319000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T00:38:39", - "duration": 7200000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T00:38:39", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-09-21T07:38:39Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T02:38:39", - "duration": 3081000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T00:00:00", - "duration": 1518000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T00:25:18", - "duration": 3600000, - "percent": 0.7, - "rate": 1.05, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T00:25:18", - "duration": 3600000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-09-22T07:25:18Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T01:25:18", - "duration": 7482000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T05:30:00", - "duration": 1230000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T05:50:30", - "duration": 18830000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T11:04:20", - "duration": 3340000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T12:00:00", - "duration": 19246000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T17:20:46", - "duration": 7200000, - "percent": 1.7, - "rate": 1.02, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T17:20:46", - "duration": 7200000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-24T00:20:46Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T17:20:46", - "duration": 2354000, - "expectedDuration": 7200000, - "percent": 1.7, - "rate": 1.02, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T17:20:46", - "duration": 7200000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-24T00:20:46Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T18:00:00", - "duration": 7200000, - "percent": 1.7, - "rate": 1.78, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T18:00:00", - "duration": 7200000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-09-24T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T18:00:00", - "duration": 4846000, - "expectedDuration": 7200000, - "percent": 1.7, - "rate": 1.78, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T18:00:00", - "duration": 7200000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-09-24T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T19:20:46", - "duration": 9554000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T08:30:00", - "duration": 2085000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T09:04:45", - "duration": 4217000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T10:15:02", - "duration": 6298000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T12:00:00", - "duration": 17944000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T16:59:04", - "duration": 3600000, - "percent": 1.65, - "rate": 0.99, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T16:59:04", - "duration": 3600000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-26T23:59:04Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T17:59:04", - "duration": 56000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T18:00:00", - "duration": 5666000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T19:34:26", - "duration": 5400000, - "percent": 1.9, - "rate": 1.99, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T19:34:26", - "duration": 5400000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-09-27T02:34:26Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T21:04:26", - "duration": 3334000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T00:00:00", - "duration": 2082000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T00:34:42", - "duration": 3600000, - "percent": 1.35, - "rate": 2.02, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T00:34:42", - "duration": 3600000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-09-27T07:34:42Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T01:34:42", - "duration": 6918000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T12:00:00", - "duration": 5752000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T13:35:52", - "duration": 204000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T13:39:16", - "duration": 5345000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T15:08:21", - "duration": 5400000, - "percent": 1.55, - "rate": 0.93, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T15:08:21", - "duration": 5400000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-27T22:08:21Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T16:38:21", - "duration": 4899000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T18:00:00", - "duration": 6720000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T19:52:00", - "duration": 645000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T20:02:45", - "duration": 7035000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T05:30:00", - "duration": 9805000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:13:25", - "duration": 5400000, - "percent": 1.5, - "rate": 2.32, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:13:25", - "duration": 5400000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-09-28T15:13:25Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:13:25", - "duration": 995000, - "expectedDuration": 5400000, - "percent": 1.5, - "rate": 2.32, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:13:25", - "duration": 5400000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-09-28T15:13:25Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:30:00", - "duration": 5400000, - "percent": 1.5, - "rate": 2.1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:30:00", - "duration": 5400000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-09-28T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:30:00", - "duration": 4405000, - "expectedDuration": 5400000, - "percent": 1.5, - "rate": 2.1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:30:00", - "duration": 5400000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-09-28T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T09:43:25", - "duration": 8195000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T12:00:00", - "duration": 2532000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T12:42:12", - "duration": 4620000, - "percent": 1.4, - "rate": 0.84, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T12:42:12", - "duration": 4620000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-28T19:42:12Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T12:42:12", - "duration": 4596000, - "expectedDuration": 4620000, - "percent": 1.4, - "rate": 0.84, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T12:42:12", - "duration": 4620000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-28T19:42:12Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T13:58:48", - "duration": 14000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T13:59:02", - "duration": 5400000, - "percent": 1.55, - "rate": 0.93, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T13:59:02", - "duration": 5400000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-28T20:59:02Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T15:29:02", - "duration": 6819000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T17:22:41", - "duration": 7200000, - "percent": 1.35, - "rate": 0.81, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T17:22:41", - "duration": 7200000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-29T00:22:41Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T17:22:41", - "duration": 2239000, - "expectedDuration": 7200000, - "percent": 1.35, - "rate": 0.81, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T17:22:41", - "duration": 7200000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-29T00:22:41Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T18:00:00", - "duration": 7200000, - "percent": 1.35, - "rate": 1.41, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T18:00:00", - "duration": 7200000, - "rate": 1.04, - "scheduleName": "basal 3", - "time": "2018-09-29T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T18:00:00", - "duration": 4961000, - "expectedDuration": 7200000, - "percent": 1.35, - "rate": 1.41, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T18:00:00", - "duration": 7200000, - "rate": 1.04, - "scheduleName": "basal 3", - "time": "2018-09-29T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T19:22:41", - "duration": 9439000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T00:00:00", - "duration": 9113000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T02:31:53", - "duration": 5400000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T02:31:53", - "duration": 5400000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-09-29T09:31:53Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T02:31:53", - "duration": 3487000, - "expectedDuration": 5400000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T02:31:53", - "duration": 5400000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-09-29T09:31:53Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T03:30:00", - "duration": 5400000, - "percent": 1.25, - "rate": 1.68, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T03:30:00", - "duration": 5400000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-09-29T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T03:30:00", - "duration": 1913000, - "expectedDuration": 5400000, - "percent": 1.25, - "rate": 1.68, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T03:30:00", - "duration": 5400000, - "rate": 1.34, - "scheduleName": "basal 3", - "time": "2018-09-29T10:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T04:01:53", - "duration": 5287000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T08:30:00", - "duration": 4914000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T09:51:54", - "duration": 9000000, - "percent": 0.8, - "rate": 1.12, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T09:51:54", - "duration": 9000000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-09-29T16:51:54Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T09:51:54", - "duration": 7686000, - "expectedDuration": 9000000, - "percent": 0.8, - "rate": 1.12, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T09:51:54", - "duration": 9000000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-09-29T16:51:54Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T12:00:00", - "duration": 9000000, - "percent": 0.8, - "rate": 0.48, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T12:00:00", - "duration": 9000000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-29T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T12:00:00", - "duration": 1314000, - "expectedDuration": 9000000, - "percent": 0.8, - "rate": 0.48, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T12:00:00", - "duration": 9000000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-29T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T12:21:54", - "duration": 20286000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T18:00:00", - "duration": 1416000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T18:23:36", - "duration": 10800000, - "percent": 1.5, - "rate": 1.57, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T18:23:36", - "duration": 10800000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-09-30T01:23:36Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T21:23:36", - "duration": 2184000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T08:30:00", - "duration": 3040000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T09:20:40", - "duration": 3159000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T10:13:19", - "duration": 6401000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T12:00:00", - "duration": 4788000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T13:19:48", - "duration": 7200000, - "percent": 1.45, - "rate": 0.87, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T13:19:48", - "duration": 7200000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-30T20:19:48Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T15:19:48", - "duration": 4339000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T16:32:07", - "duration": 7200000, - "percent": 1.5, - "rate": 0.9, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T16:32:07", - "duration": 7200000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-30T23:32:07Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T16:32:07", - "duration": 5273000, - "expectedDuration": 7200000, - "percent": 1.5, - "rate": 0.9, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T16:32:07", - "duration": 7200000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-09-30T23:32:07Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T18:00:00", - "duration": 7200000, - "percent": 1.5, - "rate": 1.57, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T18:00:00", - "duration": 7200000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-10-01T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T18:00:00", - "duration": 1927000, - "expectedDuration": 7200000, - "percent": 1.5, - "rate": 1.57, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T18:00:00", - "duration": 7200000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-10-01T01:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T18:32:07", - "duration": 12473000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T18:00:00", - "duration": 4755000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T19:19:15", - "duration": 9000000, - "percent": 1.5, - "rate": 1.57, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T19:19:15", - "duration": 9000000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-10-02T02:19:15Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T21:49:15", - "duration": 645000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T18:00:00", - "duration": 12431000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T21:27:11", - "duration": 10800000, - "percent": 1.95, - "rate": 2.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T21:27:11", - "duration": 10800000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-10-03T04:27:11Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T21:27:11", - "duration": 1969000, - "expectedDuration": 10800000, - "percent": 1.95, - "rate": 2.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T21:27:11", - "duration": 10800000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-10-03T04:27:11Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T22:00:00", - "duration": 10800000, - "percent": 1.95, - "rate": 2.73, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T22:00:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-03T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T22:00:00", - "duration": 7200000, - "expectedDuration": 10800000, - "percent": 1.95, - "rate": 2.73, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T22:00:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-03T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T00:00:00", - "duration": 10800000, - "percent": 1.95, - "rate": 2.92, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T00:00:00", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-10-03T07:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T00:00:00", - "duration": 1631000, - "expectedDuration": 10800000, - "percent": 1.95, - "rate": 2.92, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T00:00:00", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3", - "time": "2018-10-03T07:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T00:27:11", - "duration": 10969000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T18:00:00", - "duration": 260000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T18:04:20", - "duration": 3314000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T18:59:34", - "duration": 7000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T18:59:41", - "duration": 45000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T19:00:26", - "duration": 10774000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T05:30:00", - "duration": 7859000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T07:40:59", - "duration": 36000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T07:41:35", - "duration": 2905000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T08:30:00", - "duration": 5764000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T10:06:04", - "duration": 7200000, - "percent": 1.25, - "rate": 1.75, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T10:06:04", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-04T17:06:04Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T10:06:04", - "duration": 6836000, - "expectedDuration": 7200000, - "percent": 1.25, - "rate": 1.75, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T10:06:04", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-04T17:06:04Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T12:00:00", - "duration": 7200000, - "percent": 1.25, - "rate": 0.75, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T12:00:00", - "duration": 7200000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-10-04T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T12:00:00", - "duration": 364000, - "expectedDuration": 7200000, - "percent": 1.25, - "rate": 0.75, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T12:00:00", - "duration": 7200000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-10-04T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T12:06:04", - "duration": 21236000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T08:30:00", - "duration": 11084000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T11:34:44", - "duration": 3600000, - "percent": 0.7, - "rate": 0.98, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T11:34:44", - "duration": 3600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-05T18:34:44Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T11:34:44", - "duration": 1516000, - "expectedDuration": 3600000, - "percent": 0.7, - "rate": 0.98, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T11:34:44", - "duration": 3600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-05T18:34:44Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T12:00:00", - "duration": 3600000, - "percent": 0.7, - "rate": 0.42, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T12:00:00", - "duration": 3600000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-10-05T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T12:00:00", - "duration": 2084000, - "expectedDuration": 3600000, - "percent": 0.7, - "rate": 0.42, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T12:00:00", - "duration": 3600000, - "rate": 0.6, - "scheduleName": "basal 3", - "time": "2018-10-05T19:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T12:34:44", - "duration": 19516000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T12:00:00", - "duration": 12872000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T15:34:32", - "duration": 4983000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T16:57:35", - "duration": 3745000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T18:00:00", - "duration": 5583000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T19:33:03", - "duration": 7200000, - "percent": 1.55, - "rate": 1.62, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T19:33:03", - "duration": 7200000, - "rate": 1.05, - "scheduleName": "basal 3", - "time": "2018-10-07T02:33:03Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T21:33:03", - "duration": 1617000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T00:00:00", - "duration": 2776000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T00:46:16", - "duration": 7200000, - "percent": 1.3, - "rate": 2.01, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T00:46:16", - "duration": 7200000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-10-07T07:46:16Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T02:46:16", - "duration": 2624000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T22:00:00", - "duration": 1978000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T22:32:58", - "duration": 14400000, - "percent": 1.75, - "rate": 2.45, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T22:32:58", - "duration": 14400000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-08T05:32:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T22:32:58", - "duration": 5222000, - "expectedDuration": 14400000, - "percent": 1.75, - "rate": 2.45, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T22:32:58", - "duration": 14400000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-08T05:32:58Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T00:00:00", - "duration": 14400000, - "percent": 1.75, - "rate": 2.71, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T00:00:00", - "duration": 14400000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-10-08T07:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T00:00:00", - "duration": 9178000, - "expectedDuration": 14400000, - "percent": 1.75, - "rate": 2.71, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T00:00:00", - "duration": 14400000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-10-08T07:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T02:32:58", - "duration": 3422000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T05:30:00", - "duration": 8216000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T07:46:56", - "duration": 670000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T07:58:06", - "duration": 9000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T07:58:15", - "duration": 3600000, - "percent": 1.45, - "rate": 2.24, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T07:58:15", - "duration": 3600000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-10-09T14:58:15Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T07:58:15", - "duration": 1905000, - "expectedDuration": 3600000, - "percent": 1.45, - "rate": 2.24, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T07:58:15", - "duration": 3600000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-10-09T14:58:15Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T08:30:00", - "duration": 3600000, - "percent": 1.45, - "rate": 2.03, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T08:30:00", - "duration": 3600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-09T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T08:30:00", - "duration": 1695000, - "expectedDuration": 3600000, - "percent": 1.45, - "rate": 2.03, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T08:30:00", - "duration": 3600000, - "rate": 1.4, - "scheduleName": "basal 3", - "time": "2018-10-09T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T08:58:15", - "duration": 10905000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T18:00:00", - "duration": 1977000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T18:32:57", - "duration": 4784000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T19:52:41", - "duration": 7639000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T08:30:00", - "duration": 993000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T08:46:33", - "duration": 11607000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T03:30:00", - "duration": 14251000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T07:27:31", - "duration": 3604000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T08:27:35", - "duration": 145000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T12:00:00", - "duration": 1528000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T12:25:28", - "duration": 5400000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T12:25:28", - "duration": 5400000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-10-12T19:25:28Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T12:25:28", - "duration": 5399000, - "expectedDuration": 5400000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T12:25:28", - "duration": 5400000, - "rate": 0.64, - "scheduleName": "basal 3", - "time": "2018-10-12T19:25:28Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T13:55:27", - "duration": 14673000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:00:00", - "duration": 887000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:14:47", - "duration": 60000, - "percent": 0.6, - "rate": 0.99, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:14:47", - "duration": 60000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-13T07:14:47Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:14:47", - "duration": 17000, - "expectedDuration": 60000, - "percent": 0.6, - "rate": 0.99, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:14:47", - "duration": 60000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-13T07:14:47Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:15:04", - "duration": 23000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:15:27", - "duration": 3147000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T01:07:54", - "duration": 435000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T04:15:09", - "duration": 14000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T04:15:23", - "duration": 9240000, - "percent": 0.65, - "rate": 1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T04:15:23", - "duration": 9240000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-10-13T08:15:23Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T04:15:23", - "duration": 9089000, - "expectedDuration": 9240000, - "percent": 0.65, - "rate": 1, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T04:15:23", - "duration": 9240000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-10-13T08:15:23Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T06:46:52", - "duration": 297000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T06:51:49", - "duration": 17000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T06:52:06", - "duration": 3600000, - "percent": 0.85, - "rate": 1.31, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T06:52:06", - "duration": 3600000, - "rate": 1.54, - "scheduleName": "basal 3", - "time": "2018-10-13T10:52:06Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T07:52:06", - "duration": 2274000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T18:00:00", - "duration": 10401000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T20:53:21", - "duration": 16200000, - "percent": 1.65, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T20:53:21", - "duration": 16200000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-14T00:53:21Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T20:53:21", - "duration": 3999000, - "expectedDuration": 16200000, - "percent": 1.65, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T20:53:21", - "duration": 16200000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-14T00:53:21Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T22:00:00", - "duration": 16200000, - "percent": 1.65, - "rate": 2.39, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T22:00:00", - "duration": 16200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-14T02:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T22:00:00", - "duration": 7200000, - "expectedDuration": 16200000, - "percent": 1.65, - "rate": 2.39, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T22:00:00", - "duration": 16200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-14T02:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T00:00:00", - "duration": 16200000, - "percent": 1.65, - "rate": 2.72, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T00:00:00", - "duration": 16200000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-14T04:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T00:00:00", - "duration": 5001000, - "expectedDuration": 16200000, - "percent": 1.65, - "rate": 2.72, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T00:00:00", - "duration": 16200000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-14T04:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T01:23:21", - "duration": 566000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T01:32:47", - "duration": 12600000, - "percent": 1.65, - "rate": 2.72, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T01:32:47", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-14T05:32:47Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T01:32:47", - "duration": 7033000, - "expectedDuration": 12600000, - "percent": 1.65, - "rate": 2.72, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T01:32:47", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-14T05:32:47Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T03:30:00", - "duration": 12600000, - "percent": 1.65, - "rate": 2.55, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T03:30:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-10-14T07:30:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T03:30:00", - "duration": 5567000, - "expectedDuration": 12600000, - "percent": 1.65, - "rate": 2.55, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T03:30:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-10-14T07:30:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T05:02:47", - "duration": 12433000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T12:00:00", - "duration": 18910000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T17:15:10", - "duration": 10800000, - "percent": 1.45, - "rate": 0.94, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T17:15:10", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-14T21:15:10Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T17:15:10", - "duration": 2690000, - "expectedDuration": 10800000, - "percent": 1.45, - "rate": 0.94, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T17:15:10", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-14T21:15:10Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T18:00:00", - "duration": 10800000, - "percent": 1.45, - "rate": 1.66, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T18:00:00", - "duration": 10800000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-10-14T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T18:00:00", - "duration": 8110000, - "expectedDuration": 10800000, - "percent": 1.45, - "rate": 1.66, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T18:00:00", - "duration": 10800000, - "rate": 1.14, - "scheduleName": "basal 3", - "time": "2018-10-14T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T20:15:10", - "duration": 6290000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T12:00:00", - "duration": 8739000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T14:25:39", - "duration": 1563000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T14:51:42", - "duration": 5877000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T16:29:39", - "duration": 10800000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T16:29:39", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-15T20:29:39Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T16:29:39", - "duration": 5421000, - "expectedDuration": 10800000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T16:29:39", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-15T20:29:39Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T18:00:00", - "duration": 10800000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T18:00:00", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-15T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T18:00:00", - "duration": 5379000, - "expectedDuration": 10800000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T18:00:00", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-15T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T19:29:39", - "duration": 9021000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T18:00:00", - "duration": 813000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T18:13:33", - "duration": 18000000, - "percent": 1.65, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T18:13:33", - "duration": 18000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-16T22:13:33Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T18:13:33", - "duration": 13587000, - "expectedDuration": 18000000, - "percent": 1.65, - "rate": 1.89, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T18:13:33", - "duration": 18000000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-16T22:13:33Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T22:00:00", - "duration": 18000000, - "percent": 1.65, - "rate": 2.39, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T22:00:00", - "duration": 18000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-17T02:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T22:00:00", - "duration": 4413000, - "expectedDuration": 18000000, - "percent": 1.65, - "rate": 2.39, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T22:00:00", - "duration": 18000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-17T02:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T23:13:33", - "duration": 2787000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T12:00:00", - "duration": 12800000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T15:33:20", - "duration": 256000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T15:37:36", - "duration": 8544000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T00:00:00", - "duration": 586000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T00:09:46", - "duration": 12600000, - "percent": 1.7, - "rate": 2.8, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T00:09:46", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-19T04:09:46Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T00:09:46", - "duration": 12014000, - "expectedDuration": 12600000, - "percent": 1.7, - "rate": 2.8, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T00:09:46", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-19T04:09:46Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T03:30:00", - "duration": 12600000, - "percent": 1.7, - "rate": 2.63, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T03:30:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-10-19T07:30:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T03:30:00", - "duration": 586000, - "expectedDuration": 12600000, - "percent": 1.7, - "rate": 2.63, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T03:30:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-10-19T07:30:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T03:39:46", - "duration": 17414000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T12:00:00", - "duration": 17302000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T16:48:22", - "duration": 7200000, - "percent": 1.6, - "rate": 1.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T16:48:22", - "duration": 7200000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-19T20:48:22Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T16:48:22", - "duration": 4298000, - "expectedDuration": 7200000, - "percent": 1.6, - "rate": 1.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T16:48:22", - "duration": 7200000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-19T20:48:22Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T18:00:00", - "duration": 7200000, - "percent": 1.6, - "rate": 1.84, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T18:00:00", - "duration": 7200000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-19T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T18:00:00", - "duration": 2902000, - "expectedDuration": 7200000, - "percent": 1.6, - "rate": 1.84, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T18:00:00", - "duration": 7200000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-19T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T18:48:22", - "duration": 11498000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T12:00:00", - "duration": 19646000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T17:27:26", - "duration": 10800000, - "percent": 1.75, - "rate": 1.13, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T17:27:26", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-20T21:27:26Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T17:27:26", - "duration": 1954000, - "expectedDuration": 10800000, - "percent": 1.75, - "rate": 1.13, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T17:27:26", - "duration": 10800000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-20T21:27:26Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T18:00:00", - "duration": 10800000, - "percent": 1.75, - "rate": 2.01, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T18:00:00", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-20T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T18:00:00", - "duration": 8846000, - "expectedDuration": 10800000, - "percent": 1.75, - "rate": 2.01, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T18:00:00", - "duration": 10800000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-20T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T20:27:26", - "duration": 5554000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T22:00:00", - "duration": 3002000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T22:50:02", - "duration": 416000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T22:56:58", - "duration": 3782000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T12:00:00", - "duration": 11357000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T15:09:17", - "duration": 12600000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T15:09:17", - "duration": 12600000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-22T19:09:17Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T15:09:17", - "duration": 10243000, - "expectedDuration": 12600000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T15:09:17", - "duration": 12600000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-22T19:09:17Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T18:00:00", - "duration": 12600000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T18:00:00", - "duration": 12600000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-22T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T18:00:00", - "duration": 2357000, - "expectedDuration": 12600000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T18:00:00", - "duration": 12600000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-22T22:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T18:39:17", - "duration": 12043000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T08:30:00", - "duration": 9912000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T11:15:12", - "duration": 9000000, - "percent": 0.4, - "rate": 0.58, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T11:15:12", - "duration": 9000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-23T15:15:12Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T11:15:12", - "duration": 2688000, - "expectedDuration": 9000000, - "percent": 0.4, - "rate": 0.58, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T11:15:12", - "duration": 9000000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-23T15:15:12Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T12:00:00", - "duration": 8340000, - "percent": 0.4, - "rate": 0.26, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T12:00:00", - "duration": 8340000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-23T16:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T12:00:00", - "duration": 5612000, - "expectedDuration": 8340000, - "percent": 0.4, - "rate": 0.26, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T12:00:00", - "duration": 8340000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-23T16:00:00Z", - "timezoneOffset": -240, - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T13:33:32", - "duration": 38000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T10:34:10", - "duration": 627000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T10:44:37", - "duration": 3600000, - "percent": 1.15, - "rate": 1.66, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T10:44:37", - "duration": 3600000, - "rate": 1.44, - "scheduleName": "basal 3", - "time": "2018-10-23T17:44:37Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T11:44:37", - "duration": 923000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T18:00:00", - "duration": 10191000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T20:49:51", - "duration": 12600000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T20:49:51", - "duration": 12600000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-24T03:49:51Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T20:49:51", - "duration": 4209000, - "expectedDuration": 12600000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T20:49:51", - "duration": 12600000, - "rate": 1.15, - "scheduleName": "basal 3", - "time": "2018-10-24T03:49:51Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T22:00:00", - "duration": 12600000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T22:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-24T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T22:00:00", - "duration": 7200000, - "expectedDuration": 12600000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T22:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-24T05:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T00:00:00", - "duration": 12600000, - "percent": 1.4, - "rate": 2.31, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-24T07:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T00:00:00", - "duration": 1191000, - "expectedDuration": 12600000, - "percent": 1.4, - "rate": 2.31, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3", - "time": "2018-10-24T07:00:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T00:19:51", - "duration": 11409000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T03:30:00", - "duration": 2088000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T04:04:48", - "duration": 20248000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T09:42:16", - "duration": 8264000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T12:00:00", - "duration": 7234000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T14:00:34", - "duration": 5400000, - "percent": 1.6, - "rate": 1.04, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T14:00:34", - "duration": 5400000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-10-25T21:00:34Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T15:30:34", - "duration": 8966000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T03:30:00", - "duration": 16729000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:08:49", - "duration": 7200000, - "percent": 1.5, - "rate": 2.32, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:08:49", - "duration": 7200000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-10-27T15:08:49Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:08:49", - "duration": 1271000, - "expectedDuration": 7200000, - "percent": 1.5, - "rate": 2.32, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:08:49", - "duration": 7200000, - "rate": 1.55, - "scheduleName": "basal 3", - "time": "2018-10-27T15:08:49Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:30:00", - "duration": 7200000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-27T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:30:00", - "duration": 5929000, - "expectedDuration": 7200000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3", - "time": "2018-10-27T15:30:00Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T10:08:49", - "duration": 6671000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T12:00:00", - "duration": 65000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T12:01:05", - "duration": 421000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T12:08:06", - "duration": 21114000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T18:00:00", - "duration": 4889000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T19:21:29", - "duration": 14570000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T23:24:19", - "duration": 2141000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T03:30:00", - "duration": 13402000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T07:13:22", - "duration": 17773000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T12:09:35", - "duration": 5452000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T13:40:27", - "duration": 9000000, - "percent": 1.5, - "rate": 0.97, - "suppressed": { - "conversionOffset": 0, - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T13:40:27", - "duration": 9000000, - "rate": 0.65, - "scheduleName": "basal 3", - "time": "2018-11-03T20:40:27Z", - "timezoneOffset": -420, - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T16:10:27", - "duration": 6573000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T03:30:00", - "duration": 6646000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T05:20:46", - "duration": 81000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T04:22:07", - "duration": 14873000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T18:00:00", - "duration": 3581000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "annotations": [{ "code": "basal/unknown-duration" }], - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T18:59:41", - "duration": 0 - } -] -` - -func GetJFBasalData() []map[string]interface{} { - data := []map[string]interface{}{} - json.Unmarshal([]byte(jfBasalStr), &data) - return data -} - -var platformBasalStr = `[ - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T22:00:00", - "duration": 1217000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T22:20:17", - "duration": 800000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-11T22:33:37", - "duration": 5183000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-12T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-13T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-14T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T00:00:00", - "duration": 7992000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T02:13:12", - "duration": 2334000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T05:52:06", - "duration": 6987000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T07:48:33", - "duration": 1140000, - "percent": 0.4, - "rate": 0.62, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T08:07:02", - "duration": 2631000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T08:50:53", - "duration": 8779000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:17:12", - "duration": 1800000, - "percent": 0.6, - "rate": 0.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:47:12", - "duration": 592000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T11:57:04", - "duration": 7200000, - "percent": 0.35, - "rate": 0.5, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.43, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T12:00:00", - "duration": 7200000, - "percent": 0.35, - "rate": 0.22, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.63, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T13:57:04", - "duration": 14576000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-15T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T08:30:00", - "duration": 3356000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T09:25:56", - "duration": 7200000, - "percent": 0.5, - "rate": 0.72, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T11:25:56", - "duration": 2044000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T12:00:00", - "duration": 1425000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T12:23:45", - "duration": 5400000, - "percent": 0.5, - "rate": 0.32, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T13:53:45", - "duration": 14775000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-16T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T00:00:00", - "duration": 2543000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T00:42:23", - "duration": 12600000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T03:30:00", - "duration": 12600000, - "percent": 0.65, - "rate": 0.84, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.29, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T04:12:23", - "duration": 4657000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T08:30:00", - "duration": 10937000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T11:32:17", - "duration": 10800000, - "percent": 0.6, - "rate": 0.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T12:00:00", - "duration": 7860000, - "percent": 0.6, - "rate": 0.39, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T13:42:37", - "duration": 47000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T13:43:24", - "duration": 10800000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T16:43:24", - "duration": 4596000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T18:00:00", - "duration": 2896000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T18:48:16", - "duration": 4862000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T20:09:18", - "duration": 6642000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-17T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-18T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-19T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T00:00:00", - "duration": 10582000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T02:56:22", - "duration": 21600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T03:30:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T05:30:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T08:30:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T08:56:22", - "duration": 11018000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T12:00:00", - "duration": 7848000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T14:10:48", - "duration": 9000000, - "percent": 1.25, - "rate": 0.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T16:40:48", - "duration": 4752000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T18:00:00", - "duration": 4786000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T19:19:46", - "duration": 492000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T19:27:58", - "duration": 9122000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-20T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-21T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T08:30:00", - "duration": 5770000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:06:10", - "duration": 1860000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:36:13", - "duration": 13000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T10:36:26", - "duration": 3600000, - "percent": 1.15, - "rate": 1.66, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T11:36:26", - "duration": 1414000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T12:00:00", - "duration": 19357000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T17:22:37", - "duration": 385000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T17:29:02", - "duration": 1858000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-22T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T12:00:00", - "duration": 499000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T12:08:19", - "duration": 9000000, - "percent": 0.55, - "rate": 0.35, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T14:38:19", - "duration": 8117000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T16:53:36", - "duration": 5400000, - "percent": 1.5, - "rate": 0.97, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T18:00:00", - "duration": 5400000, - "percent": 1.5, - "rate": 1.72, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T18:23:36", - "duration": 12984000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T22:00:00", - "duration": 1335000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-23T22:22:15", - "duration": 7200000, - "percent": 0.7, - "rate": 0.91, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T00:00:00", - "duration": 7200000, - "percent": 0.7, - "rate": 1.01, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T00:22:15", - "duration": 5651000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T01:56:26", - "duration": 16200000, - "percent": 0.5, - "rate": 0.72, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:30:00", - "duration": 6360000, - "percent": 0.5, - "rate": 0.65, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:41:53", - "duration": 14000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:42:07", - "duration": 480000, - "percent": 0.15000000000000002, - "rate": 0.19, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.27, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:49:40", - "duration": 21000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T03:50:01", - "duration": 1260000, - "rate": 0 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T04:10:44", - "duration": 17000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T04:11:01", - "duration": 25200000, - "percent": 0.30000000000000004, - "rate": 0.39, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T05:30:00", - "duration": 25200000, - "percent": 0.30000000000000004, - "rate": 0.46, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.53, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T08:30:00", - "duration": 21000000, - "percent": 0.30000000000000004, - "rate": 0.43, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.43, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T10:00:43", - "duration": 7157000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-24T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T08:30:00", - "duration": 7831000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T10:40:31", - "duration": 3660000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T11:41:01", - "duration": 26048000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T18:55:09", - "duration": 11091000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-25T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T08:30:00", - "duration": 4143000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T09:39:03", - "duration": 5400000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T11:09:03", - "duration": 3057000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-26T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T12:00:00", - "duration": 11173000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T15:06:13", - "duration": 10800000, - "percent": 0.5, - "rate": 0.32, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T18:00:00", - "duration": 10800000, - "percent": 0.5, - "rate": 0.57, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.14, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T18:06:13", - "duration": 14027000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-27T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T05:30:00", - "duration": 7330000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T07:32:10", - "duration": 8320000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T09:50:50", - "duration": 7750000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-28T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-29T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T12:00:00", - "duration": 13768000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T15:49:28", - "duration": 1919000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T13:21:27", - "duration": 16713000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T18:00:00", - "duration": 7752000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T20:09:12", - "duration": 4951000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T21:31:43", - "duration": 1697000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-11-30T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T05:30:00", - "duration": 2075000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T06:04:35", - "duration": 5400000, - "percent": 1.4, - "rate": 2.17, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T07:34:35", - "duration": 3325000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T08:30:00", - "duration": 6166000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T10:12:46", - "duration": 5400000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T11:42:46", - "duration": 1034000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-01T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-02T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T22:00:00", - "duration": 4345000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T23:12:25", - "duration": 1767000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-03T23:41:52", - "duration": 1088000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-04T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-05T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-06T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T05:30:00", - "duration": 7632000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T07:37:12", - "duration": 7359000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T09:39:51", - "duration": 8409000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-07T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-08T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-09T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T08:30:00", - "duration": 7692000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T10:38:12", - "duration": 1864000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T11:09:16", - "duration": 3044000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-10T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-11T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T18:00:00", - "duration": 11017000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T21:03:37", - "duration": 10800000, - "percent": 1.5, - "rate": 1.72, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-12T22:00:00", - "duration": 10800000, - "percent": 1.5, - "rate": 1.95, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T00:00:00", - "duration": 10800000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T00:03:37", - "duration": 12383000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T05:30:00", - "duration": 5676000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T07:04:36", - "duration": 7200000, - "percent": 0.4, - "rate": 0.62, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T08:30:00", - "duration": 7200000, - "percent": 0.4, - "rate": 0.58, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T09:04:36", - "duration": 8062000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T11:18:58", - "duration": 3600000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T12:00:00", - "duration": 3600000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T12:18:58", - "duration": 20462000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T18:00:00", - "duration": 3789000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T19:03:09", - "duration": 4406000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T20:16:35", - "duration": 6205000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-13T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-14T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T12:00:00", - "duration": 21479000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T17:57:59", - "duration": 7200000, - "percent": 1.45, - "rate": 0.94, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T18:00:00", - "duration": 7200000, - "percent": 1.45, - "rate": 1.66, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.14, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T19:57:59", - "duration": 7321000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-15T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T03:30:00", - "duration": 6942000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:25:42", - "duration": 5400000, - "percent": 1.5, - "rate": 1.95, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T05:30:00", - "duration": 5400000, - "percent": 1.5, - "rate": 2.32, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T06:55:42", - "duration": 5658000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T18:00:00", - "duration": 12497000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T21:28:17", - "duration": 2135000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-16T22:03:52", - "duration": 6968000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T00:00:00", - "duration": 4032000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T01:07:12", - "duration": 7200000, - "percent": 1.75, - "rate": 2.53, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T03:07:12", - "duration": 1368000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-17T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T22:00:00", - "duration": 4835000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-18T23:20:35", - "duration": 5400000, - "percent": 1.5, - "rate": 1.95, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T00:00:00", - "duration": 5400000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T00:50:35", - "duration": 9565000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-19T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T05:30:00", - "duration": 1701000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T05:58:21", - "duration": 50296000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T19:56:37", - "duration": 7403000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-20T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-21T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T18:00:00", - "duration": 8649000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T20:24:09", - "duration": 9000000, - "percent": 1.95, - "rate": 2.24, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T22:00:00", - "duration": 9000000, - "percent": 1.95, - "rate": 2.53, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-22T22:54:09", - "duration": 3951000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T18:00:00", - "duration": 366000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T18:06:06", - "duration": 613000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T18:16:19", - "duration": 13421000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-23T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-24T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T03:30:00", - "duration": 5480000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:01:20", - "duration": 12600000, - "percent": 1.6, - "rate": 2.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T05:30:00", - "duration": 12600000, - "percent": 1.6, - "rate": 2.48, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T08:30:00", - "duration": 12600000, - "percent": 1.6, - "rate": 2.32, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T08:31:20", - "duration": 12520000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-25T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T05:30:00", - "duration": 3692000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T06:31:32", - "duration": 14400000, - "percent": 1.65, - "rate": 2.55, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T08:30:00", - "duration": 14400000, - "percent": 1.65, - "rate": 2.39, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T10:31:32", - "duration": 5308000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T18:00:00", - "duration": 9007000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T20:30:07", - "duration": 4826000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T21:50:33", - "duration": 567000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-26T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-27T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-28T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T12:00:00", - "duration": 175000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T12:02:55", - "duration": 203000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T12:06:18", - "duration": 21222000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-29T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T22:00:00", - "duration": 5252000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-30T23:27:32", - "duration": 7200000, - "percent": 1.45, - "rate": 1.88, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T00:00:00", - "duration": 7200000, - "percent": 1.45, - "rate": 2.1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T01:27:32", - "duration": 7348000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2017-12-31T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T05:30:00", - "duration": 10163000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T08:19:23", - "duration": 227000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T08:23:10", - "duration": 410000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-01T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-02T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T08:30:00", - "duration": 1916000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T09:01:56", - "duration": 291000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T09:06:47", - "duration": 10393000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-03T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-04T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T00:00:00", - "duration": 2058000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T00:34:18", - "duration": 18000000, - "percent": 1.3, - "rate": 1.88, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T03:30:00", - "duration": 18000000, - "percent": 1.3, - "rate": 1.69, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T05:30:00", - "duration": 18000000, - "percent": 1.3, - "rate": 2.01, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T05:34:18", - "duration": 10542000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-05T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T00:00:00", - "duration": 5352000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T01:29:12", - "duration": 16200000, - "percent": 1.45, - "rate": 2.1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T03:30:00", - "duration": 16200000, - "percent": 1.45, - "rate": 1.88, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T05:30:00", - "duration": 16200000, - "percent": 1.45, - "rate": 2.24, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T05:59:12", - "duration": 9048000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T08:30:00", - "duration": 10301000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T11:21:41", - "duration": 1674000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T11:49:35", - "duration": 625000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-06T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-07T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-08T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T12:00:00", - "duration": 10354000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T14:52:34", - "duration": 729000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T15:04:43", - "duration": 10517000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-09T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T05:30:00", - "duration": 6107000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T07:11:47", - "duration": 3600000, - "percent": 0.35, - "rate": 0.54, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T08:11:47", - "duration": 1093000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-10T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T08:30:00", - "duration": 5259000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T09:57:39", - "duration": 54000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T09:58:33", - "duration": 7287000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-11T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T22:00:00", - "duration": 4793000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-12T23:19:53", - "duration": 5171000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T00:46:04", - "duration": 9836000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-13T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T12:00:00", - "duration": 19060000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T17:17:40", - "duration": 298000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T17:22:38", - "duration": 2242000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-14T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-15T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-16T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T18:00:00", - "duration": 762000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T18:12:42", - "duration": 364000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T18:18:46", - "duration": 13274000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-17T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-18T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T08:30:00", - "duration": 3806000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T09:33:26", - "duration": 32400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T12:00:00", - "duration": 32400000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T18:00:00", - "duration": 32400000, - "percent": 0.75, - "rate": 0.86, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T18:33:26", - "duration": 12394000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-19T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T08:30:00", - "duration": 12207000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T11:53:27", - "duration": 10800000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T12:00:00", - "duration": 10800000, - "percent": 0.65, - "rate": 0.42, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T14:53:27", - "duration": 11193000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-20T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T00:00:00", - "duration": 4261000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T01:11:01", - "duration": 404000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T01:17:45", - "duration": 7935000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-21T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-22T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-23T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T08:30:00", - "duration": 1757000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T08:59:17", - "duration": 695000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T09:10:52", - "duration": 10148000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-24T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-25T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-26T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T12:00:00", - "duration": 18043000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T17:00:43", - "duration": 2404000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T17:40:47", - "duration": 1153000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-27T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-28T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-29T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-30T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T00:00:00", - "duration": 4572000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T01:16:12", - "duration": 303000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T01:21:15", - "duration": 7725000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T08:30:00", - "duration": 1219000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T08:50:19", - "duration": 5400000, - "percent": 1.3, - "rate": 1.88, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T10:20:19", - "duration": 5981000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-01-31T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-01T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T12:00:00", - "duration": 14758000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T16:05:58", - "duration": 375000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T16:12:13", - "duration": 6467000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T18:00:00", - "duration": 11599000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T21:13:19", - "duration": 711000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T21:25:10", - "duration": 2090000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-02T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T18:00:00", - "duration": 10305000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T20:51:45", - "duration": 7200000, - "percent": 0.19999999999999996, - "rate": 0.23, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T22:00:00", - "duration": 7200000, - "percent": 0.19999999999999996, - "rate": 0.28, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-03T22:51:45", - "duration": 4095000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-04T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T12:00:00", - "duration": 19370000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T17:22:50", - "duration": 3600000, - "percent": 0.7, - "rate": 0.45, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T18:00:00", - "duration": 3600000, - "percent": 0.7, - "rate": 0.8, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.14, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T18:22:50", - "duration": 13030000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-05T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T03:30:00", - "duration": 7580000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T05:36:20", - "duration": 249000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T05:40:29", - "duration": 10171000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-06T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-07T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T08:30:00", - "duration": 169000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T08:32:49", - "duration": 544000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T08:41:53", - "duration": 11887000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-08T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-09T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-10T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T12:00:00", - "duration": 16275000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T16:31:15", - "duration": 455000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T16:38:50", - "duration": 4870000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T18:00:00", - "duration": 13413000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T21:43:33", - "duration": 246000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T21:47:39", - "duration": 741000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-11T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-12T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-13T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-14T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:00:00", - "duration": 643000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:10:43", - "duration": 60000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:10:50", - "duration": 273000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:15:23", - "duration": 28000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T00:15:51", - "duration": 7200000, - "percent": 1.3, - "rate": 1.95, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T02:15:51", - "duration": 4449000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-15T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T00:00:00", - "duration": 10840000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:00:40", - "duration": 10800000, - "percent": 1.45, - "rate": 2.17, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T03:30:00", - "duration": 10800000, - "percent": 1.45, - "rate": 1.95, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.34, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T05:30:00", - "duration": 10800000, - "percent": 1.45, - "rate": 2.24, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T06:00:40", - "duration": 8960000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-16T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-17T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T05:30:00", - "duration": 9662000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T08:11:02", - "duration": 6831000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T10:04:53", - "duration": 973000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T10:21:06", - "duration": 97000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T10:22:43", - "duration": 5837000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T12:00:00", - "duration": 4664000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T13:17:44", - "duration": 7380000, - "percent": 1.5, - "rate": 0.97, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T15:19:49", - "duration": 9611000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-18T22:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-19T22:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-20T22:00:00", - "duration": 7200000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T05:30:00", - "duration": 7957000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T07:42:37", - "duration": 35000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T07:43:12", - "duration": 2808000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T08:30:00", - "duration": 8781000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T10:56:21", - "duration": 254000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T11:00:35", - "duration": 3565000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T00:00:00", - "duration": 4542000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T01:15:42", - "duration": 10800000, - "percent": 0.7, - "rate": 1.05, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T03:30:00", - "duration": 10800000, - "percent": 0.7, - "rate": 0.94, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.34, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T04:15:42", - "duration": 4458000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T18:00:00", - "duration": 366000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T18:06:06", - "duration": 21600000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-22T22:00:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T00:00:00", - "duration": 21600000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T00:06:06", - "duration": 9204000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T02:39:30", - "duration": 18000000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T03:30:00", - "duration": 18000000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.35, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T05:30:00", - "duration": 18000000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T07:39:30", - "duration": 3030000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T08:30:00", - "duration": 8164000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T10:46:04", - "duration": 18000000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T12:00:00", - "duration": 18000000, - "percent": 0.65, - "rate": 0.42, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T15:46:04", - "duration": 8036000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-23T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T12:00:00", - "duration": 21410000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T17:56:50", - "duration": 2163000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T18:32:53", - "duration": 12427000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T22:00:00", - "duration": 5415000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-25T23:30:15", - "duration": 7200000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T00:00:00", - "duration": 7200000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T01:30:15", - "duration": 7185000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T08:30:00", - "duration": 345000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T08:35:45", - "duration": 5400000, - "percent": 0.65, - "rate": 0.94, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T10:05:45", - "duration": 6855000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T18:00:00", - "duration": 9705000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T20:41:45", - "duration": 7200000, - "percent": 1.3, - "rate": 1.49, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T22:00:00", - "duration": 7200000, - "percent": 1.3, - "rate": 1.88, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-27T22:41:45", - "duration": 4695000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T00:00:00", - "duration": 5211000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T01:26:51", - "duration": 199000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T01:30:10", - "duration": 147000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T01:32:37", - "duration": 12600000, - "percent": 0.75, - "rate": 1.12, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.49, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T03:30:00", - "duration": 12600000, - "percent": 0.75, - "rate": 1.01, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.35, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T05:02:37", - "duration": 1643000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-02-28T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-01T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T12:00:00", - "duration": 91000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T12:01:31", - "duration": 7200000, - "percent": 1.35, - "rate": 0.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T14:01:31", - "duration": 14309000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T00:00:00", - "duration": 8771000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T02:26:11", - "duration": 272000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T02:30:43", - "duration": 3557000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-03T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-04T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T08:30:00", - "duration": 5906000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T10:08:26", - "duration": 2274000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T10:46:20", - "duration": 4420000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-06T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-07T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-08T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T18:00:00", - "duration": 2434000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T18:40:34", - "duration": 3332000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T19:36:06", - "duration": 8634000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-09T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-10T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T22:00:00", - "duration": 7042000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T23:57:22", - "duration": 114000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-11T23:59:16", - "duration": 44000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-12T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T08:30:00", - "duration": 135000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T08:32:15", - "duration": 360000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T09:38:15", - "duration": 8505000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-13T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T00:00:00", - "duration": 5721000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T01:35:21", - "duration": 660000, - "percent": 0.6, - "rate": 0.9, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T01:45:59", - "duration": 6241000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T18:00:00", - "duration": 12763000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T21:32:43", - "duration": 200000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T21:36:03", - "duration": 1437000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-15T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T00:00:00", - "duration": 7717000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T02:08:37", - "duration": 9000000, - "percent": 1.2, - "rate": 1.8, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T03:30:00", - "duration": 9000000, - "percent": 1.2, - "rate": 1.62, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.35, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T04:38:37", - "duration": 3083000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-16T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-17T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T00:00:00", - "duration": 1387000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T00:23:07", - "duration": 5575000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T01:56:02", - "duration": 5638000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-18T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-19T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T00:00:00", - "duration": 5074000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T01:24:34", - "duration": 3600000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T02:24:34", - "duration": 3926000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T12:00:00", - "duration": 14636000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T16:03:56", - "duration": 156000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T16:06:32", - "duration": 6808000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-20T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-22T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T12:00:00", - "duration": 261000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T12:04:21", - "duration": 241000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T12:08:22", - "duration": 21098000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-23T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T08:30:00", - "duration": 5750000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T10:05:50", - "duration": 188000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T10:08:58", - "duration": 6662000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-25T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T12:00:00", - "duration": 17191000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T16:46:31", - "duration": 4727000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T18:05:18", - "duration": 14082000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T18:00:00", - "duration": 2581000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T18:43:01", - "duration": 67000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T21:44:08", - "duration": 952000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-28T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T18:00:00", - "duration": 9738000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T20:42:18", - "duration": 1004000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T20:59:02", - "duration": 3658000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-29T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T00:00:00", - "duration": 12403000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:26:43", - "duration": 7200000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T03:30:00", - "duration": 7200000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.35, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T05:26:43", - "duration": 197000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-30T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-03-31T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T18:00:00", - "duration": 3804000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T19:03:24", - "duration": 476000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T19:11:20", - "duration": 10120000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-01T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T08:30:00", - "duration": 3078000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T09:21:18", - "duration": 5400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T10:51:18", - "duration": 4122000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-03T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T18:00:00", - "duration": 8562000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T20:22:42", - "duration": 87000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T17:24:09", - "duration": 2151000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T18:00:00", - "duration": 10423000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T20:53:43", - "duration": 2326000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T21:32:29", - "duration": 1651000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-04T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-06T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T08:30:00", - "duration": 11164000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T11:36:04", - "duration": 7381000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T13:39:05", - "duration": 15655000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-07T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-08T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T18:00:00", - "duration": 6679000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T19:51:19", - "duration": 1653000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T20:18:52", - "duration": 6068000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-09T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T08:30:00", - "duration": 6131000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T10:12:11", - "duration": 1800000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T10:42:11", - "duration": 4669000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-10T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T12:00:00", - "duration": 243000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T12:04:03", - "duration": 36000000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T18:00:00", - "duration": 36000000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T22:00:00", - "duration": 36000000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-11T22:04:02", - "duration": 6958000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T08:30:00", - "duration": 321000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T08:35:21", - "duration": 28800000, - "percent": 0.7, - "rate": 1.01, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T12:00:00", - "duration": 28200000, - "percent": 0.7, - "rate": 0.45, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T16:25:06", - "duration": 17000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T16:25:23", - "duration": 12600000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T18:00:00", - "duration": 12600000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T19:55:23", - "duration": 7477000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T22:00:00", - "duration": 5512000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T23:31:52", - "duration": 351000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T23:37:43", - "duration": 562000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-12T23:47:05", - "duration": 36000000, - "percent": 0.6, - "rate": 0.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:00:00", - "duration": 840000, - "percent": 0.6, - "rate": 0.9, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:01:02", - "duration": 13000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T00:01:15", - "duration": 10380000, - "percent": 0.5, - "rate": 0.75, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T02:54:02", - "duration": 17000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T02:54:19", - "duration": 27000000, - "percent": 0.35, - "rate": 0.52, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.49, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T03:30:00", - "duration": 27000000, - "percent": 0.35, - "rate": 0.47, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.34, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T05:30:00", - "duration": 14700000, - "percent": 0.35, - "rate": 0.54, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T06:59:14", - "duration": 5446000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T08:30:00", - "duration": 1684000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T08:58:04", - "duration": 3600000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T09:58:04", - "duration": 211000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T10:01:35", - "duration": 3600000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T11:01:35", - "duration": 3505000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T12:00:00", - "duration": 1514000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T12:25:14", - "duration": 12840000, - "percent": 0.55, - "rate": 0.35, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T15:58:44", - "duration": 8000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T15:58:52", - "duration": 5400000, - "percent": 1.25, - "rate": 0.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T17:28:52", - "duration": 1868000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T18:00:00", - "duration": 4291000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T19:11:31", - "duration": 60000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T19:12:19", - "duration": 10061000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-13T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T00:00:00", - "duration": 2499000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T00:41:39", - "duration": 7200000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T02:41:39", - "duration": 2901000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T05:30:00", - "duration": 10759000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T08:29:19", - "duration": 4125000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T09:38:04", - "duration": 8516000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T12:00:00", - "duration": 4493000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T13:14:53", - "duration": 3600000, - "percent": 0.9, - "rate": 0.58, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T14:14:53", - "duration": 13507000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-15T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-16T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T05:30:00", - "duration": 8560000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T07:52:40", - "duration": 8961000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T10:22:01", - "duration": 5879000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T22:00:00", - "duration": 6208000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-17T23:43:28", - "duration": 7200000, - "percent": 1.1, - "rate": 1.59, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T00:00:00", - "duration": 7200000, - "percent": 1.1, - "rate": 1.65, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T01:43:28", - "duration": 6392000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T12:00:00", - "duration": 11187000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T15:06:27", - "duration": 3600000, - "percent": 0.7, - "rate": 0.45, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T16:06:27", - "duration": 6813000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-18T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-19T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T08:30:00", - "duration": 7374000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T10:32:54", - "duration": 790000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T10:46:04", - "duration": 4436000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-20T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T05:30:00", - "duration": 10425000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T08:23:45", - "duration": 375000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T12:00:00", - "duration": 10788000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T14:59:48", - "duration": 3678000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T16:01:06", - "duration": 7134000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T12:00:00", - "duration": 9679000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T14:41:19", - "duration": 10800000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T17:41:19", - "duration": 1121000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-22T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T22:00:00", - "duration": 4227000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T23:10:27", - "duration": 586000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-23T23:20:13", - "duration": 2387000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T18:00:00", - "duration": 13412000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T21:43:32", - "duration": 200000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T21:46:52", - "duration": 788000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-25T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T00:00:00", - "duration": 3746000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:02:26", - "duration": 180000, - "percent": 0.7, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:04:34", - "duration": 11000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T01:04:45", - "duration": 18000000, - "percent": 0.85, - "rate": 1.31, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T03:30:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.19, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T05:30:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.36, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T06:04:45", - "duration": 8715000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T00:00:00", - "duration": 10498000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T02:54:58", - "duration": 21600000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T03:30:00", - "duration": 21600000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T05:30:00", - "duration": 21600000, - "percent": 0.75, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T08:30:00", - "duration": 21600000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T08:54:58", - "duration": 11102000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T22:00:00", - "duration": 4513000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T23:15:13", - "duration": 147000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-28T23:17:40", - "duration": 2540000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-29T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-04-30T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-01T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T00:00:00", - "duration": 635000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T00:10:35", - "duration": 315000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T00:15:50", - "duration": 11650000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T18:00:00", - "duration": 1631000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T18:27:11", - "duration": 3420000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T19:24:10", - "duration": 9350000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T05:30:00", - "duration": 3903000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T06:35:03", - "duration": 7200000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T08:30:00", - "duration": 7200000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T08:35:03", - "duration": 2092000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T09:09:55", - "duration": 43200000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T12:00:00", - "duration": 16200000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T13:39:54", - "duration": 221000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T13:43:35", - "duration": 10550000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T16:39:25", - "duration": 21498000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-03T22:37:43", - "duration": 4937000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T00:00:00", - "duration": 5097000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T01:24:57", - "duration": 30600000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T03:30:00", - "duration": 30600000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.35, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T05:30:00", - "duration": 30600000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T08:30:00", - "duration": 30600000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T09:54:57", - "duration": 4178000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T11:04:35", - "duration": 41400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T12:00:00", - "duration": 41400000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T18:00:00", - "duration": 41400000, - "percent": 0.75, - "rate": 0.86, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T22:00:00", - "duration": 41400000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-04T22:34:35", - "duration": 5125000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T00:00:00", - "duration": 4232000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T01:10:32", - "duration": 28800000, - "percent": 0.75, - "rate": 1.12, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.49, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T03:30:00", - "duration": 28800000, - "percent": 0.75, - "rate": 1.01, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.35, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T05:30:00", - "duration": 28800000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T08:30:00", - "duration": 28800000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T09:10:32", - "duration": 10168000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T05:30:00", - "duration": 10250000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:20:50", - "duration": 28800000, - "percent": 0.75, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T08:30:00", - "duration": 28800000, - "percent": 0.75, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T12:00:00", - "duration": 28800000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T16:20:50", - "duration": 5950000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T18:00:00", - "duration": 9910000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T20:45:10", - "duration": 257000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T20:49:27", - "duration": 4233000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-06T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-07T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-08T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-09T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T03:30:00", - "duration": 4311000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T04:41:51", - "duration": 18428000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T09:48:59", - "duration": 7861000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T18:00:00", - "duration": 11857000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T21:17:37", - "duration": 10800000, - "percent": 1.15, - "rate": 1.32, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T22:00:00", - "duration": 5460000, - "percent": 1.15, - "rate": 1.66, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T22:48:11", - "duration": 2421000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-10T23:28:32", - "duration": 3600000, - "percent": 1.25, - "rate": 1.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T00:00:00", - "duration": 3600000, - "percent": 1.25, - "rate": 1.93, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T00:28:32", - "duration": 10888000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-11T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T05:30:00", - "duration": 10800000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T12:00:00", - "duration": 21052000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T17:50:52", - "duration": 10800000, - "percent": 1.25, - "rate": 0.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T18:00:00", - "duration": 10800000, - "percent": 1.25, - "rate": 1.43, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.14, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T20:50:52", - "duration": 4148000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-12T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T03:30:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T05:30:00", - "duration": 1821000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T06:00:21", - "duration": 217000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T06:03:58", - "duration": 8762000, - "rate": 1.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-13T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T18:00:00", - "duration": 2689000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T18:44:49", - "duration": 3986000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T19:51:15", - "duration": 7725000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T18:00:00", - "duration": 8609000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T20:23:29", - "duration": 9000000, - "percent": 1.5, - "rate": 1.72, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T22:00:00", - "duration": 7140000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-15T22:21:32", - "duration": 5908000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-16T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T12:00:00", - "duration": 16133000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T16:28:53", - "duration": 113000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T16:30:46", - "duration": 5354000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-17T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-18T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-19T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T12:00:00", - "duration": 19563000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T17:26:03", - "duration": 368000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T17:32:11", - "duration": 1669000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-20T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T22:00:00", - "duration": 1859000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T22:30:59", - "duration": 3600000, - "percent": 1.95, - "rate": 2.82, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-22T23:30:59", - "duration": 1741000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T08:30:00", - "duration": 8897000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T10:58:17", - "duration": 1755000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T11:27:32", - "duration": 1948000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T12:00:00", - "duration": 19655000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T17:27:35", - "duration": 375000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T17:33:50", - "duration": 1570000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T18:00:00", - "duration": 13374000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T21:42:54", - "duration": 10800000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-23T22:00:00", - "duration": 10800000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T00:00:00", - "duration": 10800000, - "percent": 1.4, - "rate": 2.1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T00:42:54", - "duration": 10026000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-25T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T08:30:00", - "duration": 11426000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T11:40:26", - "duration": 7949000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T13:52:55", - "duration": 14825000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-28T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T08:30:00", - "duration": 2522000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T09:12:02", - "duration": 14514000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T13:13:56", - "duration": 17164000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T18:00:00", - "duration": 14339000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T21:58:59", - "duration": 1800000, - "percent": 0.09999999999999998, - "rate": 0.11, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.1, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T22:00:00", - "duration": 1800000, - "percent": 0.09999999999999998, - "rate": 0.14, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-29T22:28:59", - "duration": 5461000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T12:00:00", - "duration": 20380000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T17:39:40", - "duration": 3600000, - "percent": 0.65, - "rate": 0.42, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T18:00:00", - "duration": 3600000, - "percent": 0.65, - "rate": 0.74, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.14, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T18:39:40", - "duration": 12020000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T22:00:00", - "duration": 1941000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T22:32:21", - "duration": 332000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-30T22:37:53", - "duration": 4927000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-05-31T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T00:00:00", - "duration": 7844000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T02:10:44", - "duration": 5400000, - "percent": 0.6, - "rate": 0.9, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T03:30:00", - "duration": 5400000, - "percent": 0.6, - "rate": 0.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.35, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T03:40:44", - "duration": 6556000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T22:00:00", - "duration": 89000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T22:01:29", - "duration": 427000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-01T22:08:36", - "duration": 6684000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T12:00:00", - "duration": 6521000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:48:41", - "duration": 180000, - "percent": 0.6, - "rate": 0.39, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:51:15", - "duration": 329000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T13:56:44", - "duration": 5400000, - "percent": 1.2, - "rate": 0.78, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T15:26:44", - "duration": 9196000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-03T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-04T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T00:00:00", - "duration": 2718000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T00:45:18", - "duration": 410000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T00:52:08", - "duration": 9472000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T18:00:00", - "duration": 9098000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T20:31:38", - "duration": 238000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T20:35:36", - "duration": 5064000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T12:00:00", - "duration": 6090000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T13:41:30", - "duration": 277000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T13:46:07", - "duration": 8525000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-07T15:08:12", - "duration": 13000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-06T16:08:25", - "duration": 10295000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-07T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-07T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T12:00:00", - "duration": 537000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T12:08:57", - "duration": 190000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T12:12:07", - "duration": 20873000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T12:00:00", - "duration": 3798000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T13:03:18", - "duration": 482000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T14:12:18", - "duration": 13662000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-08T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T03:30:00", - "duration": 3971000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T04:36:11", - "duration": 250000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T04:40:21", - "duration": 2979000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-09T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T22:00:00", - "duration": 3091000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T22:51:31", - "duration": 1929000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-10T23:23:40", - "duration": 2180000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-11T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T12:00:00", - "duration": 2125000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T12:35:25", - "duration": 1737000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T13:04:22", - "duration": 17738000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-12T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-13T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T00:00:00", - "duration": 1723000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T00:28:43", - "duration": 27000000, - "percent": 0.65, - "rate": 0.97, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.49, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T03:30:00", - "duration": 27000000, - "percent": 0.65, - "rate": 0.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.34, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T05:30:00", - "duration": 27000000, - "percent": 0.65, - "rate": 1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T07:58:43", - "duration": 1877000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T12:00:00", - "duration": 11186000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T15:06:26", - "duration": 10709000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T18:04:55", - "duration": 14105000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-15T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-16T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-17T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T08:30:00", - "duration": 7555000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T10:35:55", - "duration": 27000000, - "percent": 0.8, - "rate": 1.16, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T12:00:00", - "duration": 27000000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T18:00:00", - "duration": 27000000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T18:05:54", - "duration": 6111000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T19:47:45", - "duration": 18000000, - "percent": 0.85, - "rate": 0.97, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.14, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-18T22:00:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.23, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T00:00:00", - "duration": 17880000, - "percent": 0.85, - "rate": 1.27, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.49, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T00:44:56", - "duration": 112000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T00:46:48", - "duration": 9792000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T18:00:00", - "duration": 10769000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T20:59:29", - "duration": 3631000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-19T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-20T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T08:30:00", - "duration": 10621000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T11:27:01", - "duration": 25200000, - "percent": 0.8, - "rate": 1.12, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T12:00:00", - "duration": 14160000, - "percent": 0.8, - "rate": 0.48, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T15:22:15", - "duration": 52000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T18:23:07", - "duration": 13013000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T22:00:00", - "duration": 6238000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T23:43:58", - "duration": 870000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-21T23:58:28", - "duration": 92000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-22T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-23T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T00:00:00", - "duration": 9249000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T02:34:09", - "duration": 9000000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T03:30:00", - "duration": 9000000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.35, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T05:04:09", - "duration": 1551000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T08:30:00", - "duration": 6845000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T10:24:05", - "duration": 10800000, - "percent": 1.35, - "rate": 1.89, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T12:00:00", - "duration": 10800000, - "percent": 1.35, - "rate": 0.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T13:24:05", - "duration": 16555000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-24T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T05:30:00", - "duration": 8167000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T07:46:07", - "duration": 5319000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T09:14:46", - "duration": 9914000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T22:00:00", - "duration": 2939000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T22:48:59", - "duration": 3600000, - "percent": 0.85, - "rate": 1.19, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-25T23:48:59", - "duration": 661000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T00:00:00", - "duration": 10930000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T03:02:10", - "duration": 56000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T00:03:06", - "duration": 12414000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-26T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T12:00:00", - "duration": 16156000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T16:29:16", - "duration": 5400000, - "percent": 1.4, - "rate": 0.84, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T17:59:16", - "duration": 44000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-27T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T12:00:00", - "duration": 7901000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T14:11:41", - "duration": 1866000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T14:42:47", - "duration": 11833000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-28T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T08:30:00", - "duration": 7554000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T10:35:54", - "duration": 27000000, - "percent": 0.85, - "rate": 1.19, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T12:00:00", - "duration": 27000000, - "percent": 0.85, - "rate": 0.51, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T18:00:00", - "duration": 27000000, - "percent": 0.85, - "rate": 0.89, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T18:05:54", - "duration": 14046000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T22:00:00", - "duration": 5283000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-06-29T23:28:03", - "duration": 3855000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T00:32:18", - "duration": 10662000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T18:00:00", - "duration": 6951000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T19:55:51", - "duration": 7449000, - "rate": 1, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-06-30T22:00:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T00:00:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T03:30:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T05:30:00", - "duration": 10800000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T08:30:00", - "duration": 10564000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T11:26:04", - "duration": 139000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T11:28:23", - "duration": 1897000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-01T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T00:00:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T03:30:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-02T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T00:00:00", - "duration": 11060000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:04:20", - "duration": 21600000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T03:30:00", - "duration": 21600000, - "percent": 0.75, - "rate": 0.93, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.24, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T05:30:00", - "duration": 19560000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T08:27:11", - "duration": 10538000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T11:22:49", - "duration": 2231000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-03T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T00:00:00", - "duration": 10459000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T02:54:19", - "duration": 7200000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T03:30:00", - "duration": 7200000, - "percent": 0.75, - "rate": 0.93, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.24, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T04:54:19", - "duration": 2141000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-04T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T00:00:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T03:30:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-05T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T00:00:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T03:30:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T18:00:00", - "duration": 4501000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T19:15:01", - "duration": 442000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T19:22:23", - "duration": 9457000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-06T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T00:00:00", - "duration": 9207000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T02:33:27", - "duration": 3600000, - "percent": 1.35, - "rate": 1.89, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T03:30:00", - "duration": 3600000, - "percent": 1.35, - "rate": 1.68, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.24, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T03:33:27", - "duration": 6993000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T05:30:00", - "duration": 10800000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T08:30:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T18:00:00", - "duration": 14400000, - "rate": 0.95, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-07T22:00:00", - "duration": 7200000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T00:00:00", - "duration": 7931000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T02:12:11", - "duration": 1802000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T02:42:13", - "duration": 2867000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-08T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-09T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T00:00:00", - "duration": 1644000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T00:27:24", - "duration": 387000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T00:33:51", - "duration": 10569000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-10T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-11T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-12T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T05:30:00", - "duration": 11850000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T08:47:30", - "duration": 7734000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T10:56:24", - "duration": 3816000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-13T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T12:00:00", - "duration": 11503000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T15:11:43", - "duration": 238000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T15:15:41", - "duration": 9859000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-14T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T00:00:00", - "duration": 11695000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:14:55", - "duration": 18000000, - "percent": 0.85, - "rate": 1.1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.29, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T03:30:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.02, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.2, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T05:30:00", - "duration": 18000000, - "percent": 0.85, - "rate": 1.1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.29, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T08:14:55", - "duration": 905000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-15T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T08:30:00", - "duration": 4149000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T09:39:09", - "duration": 6405000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T11:25:54", - "duration": 2046000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-16T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T12:00:00", - "duration": 10914000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T15:01:54", - "duration": 3600000, - "percent": 1.25, - "rate": 0.56, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T16:01:54", - "duration": 7086000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-17T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-18T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T12:00:00", - "duration": 14774000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T16:06:14", - "duration": 789000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T16:19:23", - "duration": 6037000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T18:00:00", - "duration": 5447000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T19:30:47", - "duration": 10800000, - "percent": 1.15, - "rate": 1.03, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.9, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T22:00:00", - "duration": 10800000, - "percent": 1.15, - "rate": 1.43, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.24, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-19T22:30:47", - "duration": 5353000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-20T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-21T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T00:00:00", - "duration": 7351000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T02:02:31", - "duration": 5400000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T03:30:00", - "duration": 5400000, - "percent": 0.8, - "rate": 0.96, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.2, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T03:32:31", - "duration": 7049000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-22T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T00:00:00", - "duration": 829000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T00:13:49", - "duration": 2232000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T00:51:01", - "duration": 9539000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-23T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-24T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-25T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T08:30:00", - "duration": 1596000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T08:56:36", - "duration": 882000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T09:11:18", - "duration": 10122000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T18:00:00", - "duration": 124000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T18:02:04", - "duration": 5400000, - "percent": 0.85, - "rate": 0.76, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.89, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T19:32:04", - "duration": 8876000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-26T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-27T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-28T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T00:00:00", - "duration": 860000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T00:14:20", - "duration": 2644000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T00:58:24", - "duration": 9096000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-29T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T18:00:00", - "duration": 1335000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T18:22:15", - "duration": 5400000, - "percent": 0.4, - "rate": 0.36, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.9, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T19:52:15", - "duration": 7665000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-30T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-07-31T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T00:00:00", - "duration": 7906000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T02:11:46", - "duration": 21445000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T08:09:11", - "duration": 1249000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-01T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-02T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T00:00:00", - "duration": 6044000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T01:40:44", - "duration": 5880000, - "percent": 0.85, - "rate": 1.1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.29, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:18:31", - "duration": 9000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:18:40", - "duration": 7200000, - "percent": 0.7, - "rate": 0.91, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T03:30:00", - "duration": 7200000, - "percent": 0.7, - "rate": 0.84, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.2, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T05:18:40", - "duration": 680000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T12:00:00", - "duration": 8453000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T14:20:53", - "duration": 326000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T14:26:19", - "duration": 12821000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-03T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-04T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T12:00:00", - "duration": 18803000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T17:13:23", - "duration": 7200000, - "percent": 1.25, - "rate": 0.56, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T18:00:00", - "duration": 7200000, - "percent": 1.25, - "rate": 1.12, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.9, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T19:13:23", - "duration": 9106000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T21:45:09", - "duration": 251000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T21:49:20", - "duration": 640000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-05T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-06T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-07T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T05:30:00", - "duration": 9183000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T08:03:03", - "duration": 1617000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-08T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T03:30:00", - "duration": 5472000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T05:01:12", - "duration": 180000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T05:04:12", - "duration": 1548000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-09T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-10T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T18:00:00", - "duration": 13178000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T21:39:38", - "duration": 3600000, - "percent": 1.15, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.04, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T22:00:00", - "duration": 3600000, - "percent": 1.15, - "rate": 1.61, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-11T22:39:38", - "duration": 4822000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T12:00:00", - "duration": 4236000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T13:10:36", - "duration": 3620000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T14:10:56", - "duration": 3631000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T15:11:27", - "duration": 600000, - "percent": 0.8, - "rate": 0.48, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T15:21:15", - "duration": 7934000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T17:33:29", - "duration": 1591000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-12T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-13T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T00:00:00", - "duration": 8499000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T02:21:39", - "duration": 16200000, - "percent": 0.8, - "rate": 1.2, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T03:30:00", - "duration": 16200000, - "percent": 0.8, - "rate": 1.08, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.35, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T05:30:00", - "duration": 16200000, - "percent": 0.8, - "rate": 1.24, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T06:51:39", - "duration": 5901000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T18:00:00", - "duration": 3812000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T19:03:32", - "duration": 6060000, - "percent": 0.75, - "rate": 0.78, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.04, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T20:44:03", - "duration": 9000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T20:44:12", - "duration": 5400000, - "percent": 0.65, - "rate": 0.68, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T22:00:00", - "duration": 5400000, - "percent": 0.65, - "rate": 0.91, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-14T22:14:12", - "duration": 6348000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T08:30:00", - "duration": 7596000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T10:36:36", - "duration": 5004000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T18:00:00", - "duration": 57000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T18:00:57", - "duration": 10800000, - "percent": 0.19999999999999996, - "rate": 0.18, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.9, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T21:00:57", - "duration": 2953000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T21:50:10", - "duration": 240000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T21:54:10", - "duration": 350000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-15T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-16T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-17T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-18T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T05:30:00", - "duration": 1539000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T05:55:39", - "duration": 255000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T05:59:54", - "duration": 9006000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-19T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T12:00:00", - "duration": 19916000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T17:31:56", - "duration": 9000000, - "percent": 0.6, - "rate": 0.27, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T18:00:00", - "duration": 9000000, - "percent": 0.6, - "rate": 0.54, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.9, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T20:01:56", - "duration": 7084000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-20T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T12:00:00", - "duration": 12721000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T15:32:01", - "duration": 1800000, - "percent": 0.7, - "rate": 0.31, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T16:02:01", - "duration": 7079000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-21T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T12:00:00", - "duration": 6854000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T13:54:14", - "duration": 473000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T14:02:07", - "duration": 14273000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-22T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T00:00:00", - "duration": 11831000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:17:11", - "duration": 25200000, - "percent": 0.75, - "rate": 0.97, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.29, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T03:30:00", - "duration": 25200000, - "percent": 0.75, - "rate": 0.9, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.2, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T05:30:00", - "duration": 25200000, - "percent": 0.75, - "rate": 0.97, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.29, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T08:30:00", - "duration": 25200000, - "percent": 0.75, - "rate": 0.93, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.24, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T10:17:11", - "duration": 6169000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-23T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T00:00:00", - "duration": 7034000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T01:57:14", - "duration": 25200000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T03:30:00", - "duration": 25200000, - "percent": 0.8, - "rate": 0.96, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.2, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T05:30:00", - "duration": 25200000, - "percent": 0.8, - "rate": 1.04, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.3, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T08:30:00", - "duration": 25200000, - "percent": 0.8, - "rate": 1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.25, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T08:57:14", - "duration": 10966000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T12:00:00", - "duration": 8532000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T14:22:12", - "duration": 7200000, - "percent": 0.30000000000000004, - "rate": 0.13, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.43, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T16:22:12", - "duration": 5868000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-24T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T18:00:00", - "duration": 14095000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T21:54:55", - "duration": 280000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T21:59:35", - "duration": 25000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-25T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-26T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-27T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-28T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T03:30:00", - "duration": 6075000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T05:11:15", - "duration": 397000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T05:17:52", - "duration": 728000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-29T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-30T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T12:00:00", - "duration": 21600000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T18:00:00", - "duration": 14400000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-08-31T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T08:30:00", - "duration": 12600000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T12:00:00", - "duration": 4392000, - "rate": 0.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T13:13:12", - "duration": 17592000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T18:06:24", - "duration": 14016000, - "rate": 0.9, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-01T22:00:00", - "duration": 7200000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T00:00:00", - "duration": 12600000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T03:30:00", - "duration": 7200000, - "rate": 1.2, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T05:30:00", - "duration": 10800000, - "rate": 1.3, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T08:30:00", - "duration": 9169000, - "rate": 1.25, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T11:02:49", - "duration": 3431000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-02T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-03T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T05:30:00", - "duration": 4177000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T06:39:37", - "duration": 10025000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T09:26:42", - "duration": 9198000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-04T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-05T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-06T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T12:00:00", - "duration": 19217000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T17:20:17", - "duration": 6688000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T19:11:45", - "duration": 10095000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-07T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-08T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-09T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-10T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T00:00:00", - "duration": 1827000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T00:30:27", - "duration": 1374000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T00:53:21", - "duration": 9399000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-11T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-12T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-13T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T08:30:00", - "duration": 2264000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T09:07:44", - "duration": 7415000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T11:11:19", - "duration": 1593000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T11:37:52", - "duration": 5400000, - "percent": 1.35, - "rate": 1.89, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T12:00:00", - "duration": 5400000, - "percent": 1.35, - "rate": 0.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T13:07:52", - "duration": 17528000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-14T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T12:00:00", - "duration": 142000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T12:02:22", - "duration": 3600000, - "percent": 0.7, - "rate": 0.42, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T13:02:22", - "duration": 17858000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-15T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T08:30:00", - "duration": 5863000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T10:07:43", - "duration": 5400000, - "percent": 0.75, - "rate": 1.05, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T11:37:43", - "duration": 1337000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-16T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T18:00:00", - "duration": 4181000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T19:09:41", - "duration": 3495000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T20:07:56", - "duration": 6724000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-17T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-18T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T12:00:00", - "duration": 5103000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T13:25:03", - "duration": 76000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T13:26:19", - "duration": 16421000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T18:00:00", - "duration": 13638000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T21:47:18", - "duration": 533000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T21:56:11", - "duration": 229000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-19T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T18:00:00", - "duration": 2999000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T18:49:59", - "duration": 3600000, - "percent": 1.45, - "rate": 1.52, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T19:49:59", - "duration": 7801000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-20T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T00:00:00", - "duration": 2319000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T00:38:39", - "duration": 7200000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T02:38:39", - "duration": 3081000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-21T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T00:00:00", - "duration": 1518000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T00:25:18", - "duration": 3600000, - "percent": 0.7, - "rate": 1.05, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T01:25:18", - "duration": 7482000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-22T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T05:30:00", - "duration": 1230000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T05:50:30", - "duration": 18830000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T11:04:20", - "duration": 3340000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T12:00:00", - "duration": 19246000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T17:20:46", - "duration": 7200000, - "percent": 1.7, - "rate": 1.02, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T18:00:00", - "duration": 7200000, - "percent": 1.7, - "rate": 1.78, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T19:20:46", - "duration": 9554000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-23T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T08:30:00", - "duration": 2085000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T09:04:45", - "duration": 4217000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T10:15:02", - "duration": 6298000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-24T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-25T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T12:00:00", - "duration": 17944000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T16:59:04", - "duration": 3600000, - "percent": 1.65, - "rate": 0.99, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T17:59:04", - "duration": 56000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T18:00:00", - "duration": 5666000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T19:34:26", - "duration": 5400000, - "percent": 1.9, - "rate": 1.99, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T21:04:26", - "duration": 3334000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-26T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T00:00:00", - "duration": 2082000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T00:34:42", - "duration": 3600000, - "percent": 1.35, - "rate": 2.02, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T01:34:42", - "duration": 6918000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T12:00:00", - "duration": 5752000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T13:35:52", - "duration": 204000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T13:39:16", - "duration": 5345000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T15:08:21", - "duration": 5400000, - "percent": 1.55, - "rate": 0.93, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T16:38:21", - "duration": 4899000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T18:00:00", - "duration": 6720000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T19:52:00", - "duration": 645000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T20:02:45", - "duration": 7035000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-27T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T05:30:00", - "duration": 9805000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:13:25", - "duration": 5400000, - "percent": 1.5, - "rate": 2.32, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T08:30:00", - "duration": 5400000, - "percent": 1.5, - "rate": 2.1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T09:43:25", - "duration": 8195000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T12:00:00", - "duration": 2532000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T12:42:12", - "duration": 4620000, - "percent": 1.4, - "rate": 0.84, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T13:58:48", - "duration": 14000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T13:59:02", - "duration": 5400000, - "percent": 1.55, - "rate": 0.93, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T15:29:02", - "duration": 6819000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T17:22:41", - "duration": 7200000, - "percent": 1.35, - "rate": 0.81, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T18:00:00", - "duration": 7200000, - "percent": 1.35, - "rate": 1.41, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.04, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T19:22:41", - "duration": 9439000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-28T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T00:00:00", - "duration": 9113000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T02:31:53", - "duration": 5400000, - "percent": 1.25, - "rate": 1.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T03:30:00", - "duration": 5400000, - "percent": 1.25, - "rate": 1.68, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.34, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T04:01:53", - "duration": 5287000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T08:30:00", - "duration": 4914000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T09:51:54", - "duration": 9000000, - "percent": 0.8, - "rate": 1.12, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T12:00:00", - "duration": 9000000, - "percent": 0.8, - "rate": 0.48, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T12:21:54", - "duration": 20286000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T18:00:00", - "duration": 1416000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T18:23:36", - "duration": 10800000, - "percent": 1.5, - "rate": 1.57, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T21:23:36", - "duration": 2184000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-29T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T08:30:00", - "duration": 3040000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T09:20:40", - "duration": 3159000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T10:13:19", - "duration": 6401000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T12:00:00", - "duration": 4788000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T13:19:48", - "duration": 7200000, - "percent": 1.45, - "rate": 0.87, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T15:19:48", - "duration": 4339000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T16:32:07", - "duration": 7200000, - "percent": 1.5, - "rate": 0.9, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T18:00:00", - "duration": 7200000, - "percent": 1.5, - "rate": 1.57, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T18:32:07", - "duration": 12473000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-09-30T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T18:00:00", - "duration": 4755000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T19:19:15", - "duration": 9000000, - "percent": 1.5, - "rate": 1.57, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T21:49:15", - "duration": 645000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-01T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T18:00:00", - "duration": 12431000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T21:27:11", - "duration": 10800000, - "percent": 1.95, - "rate": 2.04, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-02T22:00:00", - "duration": 10800000, - "percent": 1.95, - "rate": 2.73, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T00:00:00", - "duration": 10800000, - "percent": 1.95, - "rate": 2.92, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.5, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T00:27:11", - "duration": 10969000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T18:00:00", - "duration": 260000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T18:04:20", - "duration": 3314000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T18:59:34", - "duration": 7000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T18:59:41", - "duration": 45000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T19:00:26", - "duration": 10774000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-03T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T00:00:00", - "duration": 12600000, - "rate": 1.5, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T03:30:00", - "duration": 7200000, - "rate": 1.35, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T05:30:00", - "duration": 7859000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T07:40:59", - "duration": 36000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T07:41:35", - "duration": 2905000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T08:30:00", - "duration": 5764000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T10:06:04", - "duration": 7200000, - "percent": 1.25, - "rate": 1.75, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T12:00:00", - "duration": 7200000, - "percent": 1.25, - "rate": 0.75, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T12:06:04", - "duration": 21236000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-04T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T08:30:00", - "duration": 11084000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T11:34:44", - "duration": 3600000, - "percent": 0.7, - "rate": 0.98, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T12:00:00", - "duration": 3600000, - "percent": 0.7, - "rate": 0.42, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.6, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T12:34:44", - "duration": 19516000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-05T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T12:00:00", - "duration": 12872000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T15:34:32", - "duration": 4983000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T16:57:35", - "duration": 3745000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T18:00:00", - "duration": 5583000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T19:33:03", - "duration": 7200000, - "percent": 1.55, - "rate": 1.62, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.05, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T21:33:03", - "duration": 1617000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-06T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T00:00:00", - "duration": 2776000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T00:46:16", - "duration": 7200000, - "percent": 1.3, - "rate": 2.01, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T02:46:16", - "duration": 2624000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T22:00:00", - "duration": 1978000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-07T22:32:58", - "duration": 14400000, - "percent": 1.75, - "rate": 2.45, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T00:00:00", - "duration": 14400000, - "percent": 1.75, - "rate": 2.71, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T02:32:58", - "duration": 3422000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T05:30:00", - "duration": 10800000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T08:30:00", - "duration": 12600000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T18:00:00", - "duration": 14400000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-08T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T00:00:00", - "duration": 12600000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T03:30:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T05:30:00", - "duration": 8216000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T07:46:56", - "duration": 670000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T07:58:06", - "duration": 9000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T07:58:15", - "duration": 3600000, - "percent": 1.45, - "rate": 2.24, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T08:30:00", - "duration": 3600000, - "percent": 1.45, - "rate": 2.03, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.4, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T08:58:15", - "duration": 10905000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T12:00:00", - "duration": 21600000, - "rate": 0.6, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T18:00:00", - "duration": 1977000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T18:32:57", - "duration": 4784000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T19:52:41", - "duration": 7639000, - "rate": 1.05, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-09T22:00:00", - "duration": 7200000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T08:30:00", - "duration": 993000, - "rate": 1.4, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T08:46:33", - "duration": 11607000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-10T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-11T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T03:30:00", - "duration": 14251000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T07:27:31", - "duration": 3604000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T08:27:35", - "duration": 145000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T12:00:00", - "duration": 1528000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T12:25:28", - "duration": 5400000, - "percent": 0.75, - "rate": 0.48, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.64, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T13:55:27", - "duration": 14673000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-12T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:00:00", - "duration": 887000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:14:47", - "duration": 60000, - "percent": 0.6, - "rate": 0.99, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:15:04", - "duration": 23000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T00:15:27", - "duration": 3147000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T01:07:54", - "duration": 435000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T04:15:09", - "duration": 14000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T04:15:23", - "duration": 9240000, - "percent": 0.65, - "rate": 1, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T06:46:52", - "duration": 297000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T06:51:49", - "duration": 17000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T06:52:06", - "duration": 3600000, - "percent": 0.85, - "rate": 1.31, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.54, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T07:52:06", - "duration": 2274000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T18:00:00", - "duration": 10401000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T20:53:21", - "duration": 16200000, - "percent": 1.65, - "rate": 1.89, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-13T22:00:00", - "duration": 16200000, - "percent": 1.65, - "rate": 2.39, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T00:00:00", - "duration": 16200000, - "percent": 1.65, - "rate": 2.72, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T01:23:21", - "duration": 566000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T01:32:47", - "duration": 12600000, - "percent": 1.65, - "rate": 2.72, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T03:30:00", - "duration": 12600000, - "percent": 1.65, - "rate": 2.55, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T05:02:47", - "duration": 12433000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T12:00:00", - "duration": 18910000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T17:15:10", - "duration": 10800000, - "percent": 1.45, - "rate": 0.94, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T18:00:00", - "duration": 10800000, - "percent": 1.45, - "rate": 1.66, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.14, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T20:15:10", - "duration": 6290000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-14T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T12:00:00", - "duration": 8739000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T14:25:39", - "duration": 1563000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T14:51:42", - "duration": 5877000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T16:29:39", - "duration": 10800000, - "percent": 1.4, - "rate": 0.91, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T18:00:00", - "duration": 10800000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T19:29:39", - "duration": 9021000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-15T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T18:00:00", - "duration": 813000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T18:13:33", - "duration": 18000000, - "percent": 1.65, - "rate": 1.89, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T22:00:00", - "duration": 18000000, - "percent": 1.65, - "rate": 2.39, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-16T23:13:33", - "duration": 2787000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-17T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T12:00:00", - "duration": 12800000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T15:33:20", - "duration": 256000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T15:37:36", - "duration": 8544000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-18T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T00:00:00", - "duration": 586000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T00:09:46", - "duration": 12600000, - "percent": 1.7, - "rate": 2.8, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T03:30:00", - "duration": 12600000, - "percent": 1.7, - "rate": 2.63, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T03:39:46", - "duration": 17414000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T12:00:00", - "duration": 17302000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T16:48:22", - "duration": 7200000, - "percent": 1.6, - "rate": 1.04, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T18:00:00", - "duration": 7200000, - "percent": 1.6, - "rate": 1.84, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T18:48:22", - "duration": 11498000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-19T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T12:00:00", - "duration": 19646000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T17:27:26", - "duration": 10800000, - "percent": 1.75, - "rate": 1.13, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T18:00:00", - "duration": 10800000, - "percent": 1.75, - "rate": 2.01, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T20:27:26", - "duration": 5554000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T22:00:00", - "duration": 3002000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T22:50:02", - "duration": 416000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-20T22:56:58", - "duration": 3782000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-21T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T12:00:00", - "duration": 11357000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T15:09:17", - "duration": 12600000, - "percent": 0.8, - "rate": 0.52, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T18:00:00", - "duration": 12600000, - "percent": 0.8, - "rate": 0.92, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T18:39:17", - "duration": 12043000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-22T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T08:30:00", - "duration": 9912000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T11:15:12", - "duration": 9000000, - "percent": 0.4, - "rate": 0.58, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T12:00:00", - "duration": 8340000, - "percent": 0.4, - "rate": 0.26, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T13:33:32", - "duration": 38000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T10:34:10", - "duration": 627000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T10:44:37", - "duration": 3600000, - "percent": 1.15, - "rate": 1.66, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.44, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T11:44:37", - "duration": 923000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T18:00:00", - "duration": 10191000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T20:49:51", - "duration": 12600000, - "percent": 1.4, - "rate": 1.61, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.15, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-23T22:00:00", - "duration": 12600000, - "percent": 1.4, - "rate": 2.03, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T00:00:00", - "duration": 12600000, - "percent": 1.4, - "rate": 2.31, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T00:19:51", - "duration": 11409000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T03:30:00", - "duration": 2088000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T04:04:48", - "duration": 20248000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T09:42:16", - "duration": 8264000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-24T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T12:00:00", - "duration": 7234000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T14:00:34", - "duration": 5400000, - "percent": 1.6, - "rate": 1.04, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T15:30:34", - "duration": 8966000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-25T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-26T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T03:30:00", - "duration": 16729000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:08:49", - "duration": 7200000, - "percent": 1.5, - "rate": 2.32, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.55, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T08:30:00", - "duration": 7200000, - "percent": 1.5, - "rate": 2.17, - "suppressed": { - "deliveryType": "scheduled", - "rate": 1.45, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T10:08:49", - "duration": 6671000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T12:00:00", - "duration": 65000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T12:01:05", - "duration": 421000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T12:08:06", - "duration": 21114000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-27T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-28T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-29T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T18:00:00", - "duration": 4889000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T19:21:29", - "duration": 14570000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-30T23:24:19", - "duration": 2141000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-10-31T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-01T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-02T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T03:30:00", - "duration": 13402000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T07:13:22", - "duration": 17773000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T12:09:35", - "duration": 5452000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "temp", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T13:40:27", - "duration": 9000000, - "percent": 1.5, - "rate": 0.97, - "suppressed": { - "deliveryType": "scheduled", - "rate": 0.65, - "scheduleName": "basal 3", - "type": "basal" - } - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T16:10:27", - "duration": 6573000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-03T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T03:30:00", - "duration": 6646000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T05:20:46", - "duration": 81000 - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T04:22:07", - "duration": 14873000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-04T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T18:00:00", - "duration": 14400000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-05T22:00:00", - "duration": 7200000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T00:00:00", - "duration": 12600000, - "rate": 1.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T03:30:00", - "duration": 18000000, - "rate": 1.55, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T08:30:00", - "duration": 12600000, - "rate": 1.45, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T12:00:00", - "duration": 21600000, - "rate": 0.65, - "scheduleName": "basal 3" - }, - { - "deliveryType": "scheduled", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T18:00:00", - "duration": 3581000, - "rate": 1.15, - "scheduleName": "basal 3" - }, - { - "annotations": [{ "code": "basal/unknown-duration" }], - "deliveryType": "suspend", - "deviceId": "some-pump", - "deviceTime": "2018-11-06T18:59:41", - "duration": 0 - } -] -` - -func GetPlatformBasalData() []map[string]interface{} { - data := []map[string]interface{}{} - json.Unmarshal([]byte(platformBasalStr), &data) - return data -} - -var platformSMBG = `[ - { - "_active": true, - "_deduplicator": { "hash": "3757vg83cberlvf0mdpcsugf8epsqo3r" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-02-05T21:11:00", - "raw": { "units": "mg/dL", "value": 214 }, - "subType": "manual", - "time": "2023-02-06T06:11:00Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "b813ac02abe2633dccbe506da2f6a230", - "value": 11.8786 - }, - { - "_active": true, - "_deduplicator": { "hash": "9ulaq6mjosuemmonhot3g7si9hqh98g3" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-02-05T21:13:44", - "raw": { "units": "mg/dL", "value": 214 }, - "subType": "manual", - "time": "2023-02-06T06:13:44Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "b813ac02abe2633dccbe506da2f6a230", - "value": 11.8786 - }, - { - "_active": true, - "_deduplicator": { "hash": "a4hh520sh4c3mdr49831r5a99mvsodlv" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-02-05T21:29:16", - "raw": { "units": "mg/dL", "value": 196 }, - "subType": "manual", - "time": "2023-02-06T06:29:16Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "b813ac02abe2633dccbe506da2f6a230", - "value": 10.87947 - }, - { - "_active": true, - "_deduplicator": { "hash": "im31tbcq4nm945lef6fe6ouq1q1sd5il" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-02-05T21:29:27", - "raw": { "units": "mg/dL", "value": 196 }, - "subType": "manual", - "time": "2023-02-06T06:29:27Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "b813ac02abe2633dccbe506da2f6a230", - "value": 10.87947 - }, - { - "_active": true, - "_deduplicator": { "hash": "4g871fc9q184vu035va2tev67tjq4ff5" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-02-05T22:16:18", - "raw": { "units": "mg/dL", "value": 249 }, - "subType": "manual", - "time": "2023-02-06T07:16:18Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "b813ac02abe2633dccbe506da2f6a230", - "value": 13.82136 - }, - { - "_active": true, - "_deduplicator": { "hash": "ib5km8fru8gh3pe4hdqklk2avevh1mig" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-02-05T22:16:27", - "raw": { "units": "mg/dL", "value": 249 }, - "subType": "manual", - "time": "2023-02-06T07:16:27Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "b813ac02abe2633dccbe506da2f6a230", - "value": 13.82136 - }, - { - "_active": true, - "_deduplicator": { "hash": "n843tdkn1ebjtsuvcsi3clqg4r6jujp7" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-02-05T22:38:17", - "raw": { "units": "mg/dL", "value": 273 }, - "subType": "manual", - "time": "2023-02-06T07:38:17Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "b813ac02abe2633dccbe506da2f6a230", - "value": 15.15354 - }, - { - "_active": true, - "_deduplicator": { "hash": "anglvt19qpk2uagjir7ppoapjmffh9fu" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-03-27T07:38:59", - "raw": { "units": "mg/dL", "value": 135 }, - "subType": "manual", - "time": "2023-03-27T15:38:59Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "b813ac02abe2633dccbe506da2f6a230", - "value": 7.49351 - }, - { - "_active": true, - "_deduplicator": { "hash": "01p6pa28bec7i4fc9mburhii28ca63jg" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-04-10T10:54:40", - "raw": { "units": "mg/dL", "value": 212 }, - "subType": "manual", - "time": "2023-04-10T18:54:40Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "b813ac02abe2633dccbe506da2f6a230", - "value": 11.76759 - }, - { - "_active": true, - "_deduplicator": { "hash": "29nh08u6vjorr2u9h6va1sct36ik62fg" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-05-12T07:21:16", - "raw": { "units": "mg/dL", "value": 133 }, - "subType": "manual", - "time": "2023-05-12T15:21:16Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "b813ac02abe2633dccbe506da2f6a230", - "value": 7.38249 - }, - { - "_active": true, - "_deduplicator": { "hash": "iu7t9cj610evdrq7c3s3b1a0j7o868en" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-05-13T07:51:58", - "raw": { "units": "mg/dL", "value": 220 }, - "subType": "manual", - "time": "2023-05-13T15:51:58Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "b813ac02abe2633dccbe506da2f6a230", - "value": 12.21165 - } -]` - -var jfSMBG = `[ - { - "_active": true, - "_deduplicator": { "hash": "j4q9a6vhmjb5f7m1jic59u040rid9f8b" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-02-05T21:11:00", - "subType": "manual", - "time": "2023-02-06T06:11:00Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "upid_35d555132c1d", - "value": 11.878600700837442 - }, - { - "_active": true, - "_deduplicator": { "hash": "8ijj1jmphso7v6gro71ducposqktunuj" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-02-05T21:13:44", - "subType": "manual", - "time": "2023-02-06T06:13:44Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "upid_35d555132c1d", - "value": 11.878600700837442 - }, - { - "_active": true, - "_deduplicator": { "hash": "daftamn03o4bs9i4g69bj0vpe2iikm41" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-02-05T21:29:16", - "subType": "manual", - "time": "2023-02-06T06:29:16Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "upid_35d555132c1d", - "value": 10.879466062449245 - }, - { - "_active": true, - "_deduplicator": { "hash": "0q6de81ra2gvuik318bn8e2nfi2334n1" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-02-05T21:29:27", - "subType": "manual", - "time": "2023-02-06T06:29:27Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "upid_35d555132c1d", - "value": 10.879466062449245 - }, - { - "_active": true, - "_deduplicator": { "hash": "ve0vf4fn7g2l69geo888ptjbpd063ss3" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-02-05T22:16:18", - "subType": "manual", - "time": "2023-02-06T07:16:18Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "upid_35d555132c1d", - "value": 13.821362497703378 - }, - { - "_active": true, - "_deduplicator": { "hash": "tkba95oue98958d4426ct8fpld3vfe68" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-02-05T22:16:27", - "subType": "manual", - "time": "2023-02-06T07:16:27Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "upid_35d555132c1d", - "value": 13.821362497703378 - }, - { - "_active": true, - "_deduplicator": { "hash": "1volhr0dd869eicqaj292cgicucbm8jl" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-02-05T22:38:17", - "subType": "manual", - "time": "2023-02-06T07:38:17Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "upid_35d555132c1d", - "value": 15.153542015554306 - }, - { - "_active": true, - "_deduplicator": { "hash": "ro0m2jb88i36s7hu6kcm78d56lsdhipi" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-03-27T07:38:59", - "subType": "manual", - "time": "2023-03-27T15:38:59Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "upid_35d555132c1d", - "value": 7.49350978791147 - }, - { - "_active": true, - "_deduplicator": { "hash": "mlsuvb2v6hehl3ndg5r2kko7n5d3767a" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-04-10T10:54:40", - "subType": "manual", - "time": "2023-04-10T18:54:40Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "upid_35d555132c1d", - "value": 11.76758574101653 - }, - { - "_active": true, - "_deduplicator": { "hash": "pip6n51n6ai1fap1emaa3d0pi4890681" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-05-12T07:21:16", - "subType": "manual", - "time": "2023-05-12T15:21:16Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "upid_35d555132c1d", - "value": 7.382494828090559 - }, - { - "_active": true, - "_deduplicator": { "hash": "sbbhccl6snvsrv5bq3ks84n8i7vf8p3h" }, - "_userId": "6a452338-5064-4795-81ca-84957bad2280", - "deviceId": "some-device-id", - "deviceTime": "2023-05-13T07:51:58", - "subType": "manual", - "time": "2023-05-13T15:51:58Z", - "type": "smbg", - "units": "mmol/L", - "uploadId": "upid_35d555132c1d", - "value": 12.211645580300173 - } -]` - -func GetPlatformSMBGData() []map[string]interface{} { - data := []map[string]interface{}{} - json.Unmarshal([]byte(platformSMBG), &data) - return data -} - -func GetJellyfishSMBGData() []map[string]interface{} { - data := []map[string]interface{}{} - json.Unmarshal([]byte(jfSMBG), &data) - return data -} diff --git a/migrations/20231128_jellyfish_migration/verify/upload_blob.sh b/migrations/20231128_jellyfish_migration/verify/upload_blob.sh deleted file mode 100644 index 42fbd8d078..0000000000 --- a/migrations/20231128_jellyfish_migration/verify/upload_blob.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/bash -BLOB_FILE=$1 -USER_EMAIL=$2 -USER_PW=$3 -OUTPUT_FILE_PREFIX=$4 -UPLOADER_DIR=~/Documents/src/tidepool/uploader - -SCRIPT=$(realpath "$0") -BASE_DIR=$(dirname "$SCRIPT") - -check_val() { - if [[ -z "$1" ]]; then - echo "missing required '$2' value" - exit 2 - fi -} - -cd $UPLOADER_DIR -# config file exists in the uploader repo -source ./config/qa3.sh - -check_val $BLOB_FILE "BLOB_FILE" -check_val $USER_EMAIL "USER_EMAIL" -check_val $USER_PW "USER_PW" -check_val $API_URL "API_URL" -check_val $BASE_DIR "BASE_DIR" -check_val $UPLOADER_DIR "UPLOADER_DIR" - -start=$(date +%s) -SUCCESS=false -output='not yet run' - -UPLOAD_LOG=_upload.log -ERROR_LOG=_error.log - -if [[ -n "$OUTPUT_FILE_PREFIX" ]]; then - UPLOAD_LOG="${BASE_DIR}/${OUTPUT_FILE_PREFIX}${UPLOAD_LOG}" - ERROR_LOG="${BASE_DIR}/${OUTPUT_FILE_PREFIX}${ERROR_LOG}" -fi - -if [[ "$BLOB_FILE" =~ .*"tandem".* ]]; then - output=$(node -r @babel/register lib/drivers/tandem/cli/loader.js loader.js -f $BLOB_FILE -u $USER_EMAIL -p $USER_PW) - echo "$output" | grep -q 'upload.toPlatform: all good' && SUCCESS=true -else - output=$(node -r @babel/register lib/drivers/insulet/cli/ibf_loader.js ibf_loader.js -f $BLOB_FILE -u $USER_EMAIL -p $USER_PW) - echo "$output" | grep -q 'upload.toPlatform: all good' && SUCCESS=true -fi - -cd $BASE_DIR - -end=$(date +%s) - -if [ "$SUCCESS" = true ]; then - echo 'upload all good' - records=$(echo "$output" | grep -A100000 'attempting to upload' | grep -B100000 'device data records') - runtime=$((end - start)) - echo "{"blob":"$BLOB_FILE", "account":"$USER_EMAIL", "time": "$runtime", "records": "$records" }" >>"$UPLOAD_LOG" - echo "$records" -else - echo 'upload failed!' - error_details=$(echo "$output" | grep -A100000 'add data to dataset failed' | grep -B100000 'Offending record for error 0') - - if [[ -z "$error_details" ]]; then - error_details=$(echo "$output" | grep -A100000 'add data to dataset failed' | grep -B100000 'upload.toPlatform: failed') - fi - - if [[ -z "$error_details" ]]; then - error_details=$(echo "$output") - fi - - error_details=$(echo $error_details | tr -d '\n\t\r') - - echo "{"blob":"$BLOB_FILE", "details": {"$error_details"}" >>"$ERROR_LOG" -fi diff --git a/migrations/20231128_jellyfish_migration/verify/utils_suite_test.go b/migrations/20231128_jellyfish_migration/verify/utils_suite_test.go deleted file mode 100644 index 9700454fb2..0000000000 --- a/migrations/20231128_jellyfish_migration/verify/utils_suite_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package main_test - -import ( - "testing" - - "github.com/tidepool-org/platform/test" -) - -func TestSuite(t *testing.T) { - test.Test(t) -} diff --git a/migrations/20231128_jellyfish_migration/verify/verify.go b/migrations/20231128_jellyfish_migration/verify/verify.go deleted file mode 100644 index 3bb8c1cb56..0000000000 --- a/migrations/20231128_jellyfish_migration/verify/verify.go +++ /dev/null @@ -1,227 +0,0 @@ -package main - -import ( - "context" - "fmt" - "log" - "os" - "strings" - - "github.com/urfave/cli" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" -) - -type Verify struct { - ctx context.Context - cli *cli.App - config *config - client *mongo.Client - verificationUtil *DataVerify -} - -type config struct { - mongoURI string - findBlobs bool - verifyDeduped bool - verifyDevice bool - sameAccount bool - platformUploadID string - jellyfishUploadID string - uploadIdDeduped string - deviceID string - userID string - dataTypes string -} - -const MongoURIFlag = "uri" -const PlatformUploadIDFlag = "upload-id-platform" -const JellyfishUploadIDFlag = "upload-id-jellyfish" -const SameAccountFlag = "same-account" -const FindBlobFlag = "find-blobs" -const VerifyDedupedFlag = "verify-deduped" -const VerifyDeviceFlag = "verify-device" -const UploadIDFlag = "upload-id" -const DeviceIDFlag = "device-id" -const UserIDFlag = "user-id" -const DataTypesFlag = "data-types" -const UseSubsetFlag = "use-subset" - -func main() { - ctx := context.Background() - ctx, cancel := context.WithCancel(ctx) - defer cancel() - verifier := NewVerifier(ctx) - verifier.RunAndExit() -} - -func NewVerifier(ctx context.Context) *Verify { - return &Verify{ - config: &config{sameAccount: false}, - ctx: ctx, - cli: cli.NewApp(), - } -} - -func (m *Verify) RunAndExit() { - if err := m.Initialize(); err != nil { - log.Printf("error during Initialize [%s]", err.Error()) - os.Exit(1) - } - - m.CLI().Action = func(ctx *cli.Context) error { - - var err error - m.client, err = mongo.Connect(m.ctx, options.Client().ApplyURI(strings.TrimSpace(m.config.mongoURI))) - if err != nil { - return fmt.Errorf("unable to connect to MongoDB: %w", err) - } - defer m.client.Disconnect(m.ctx) - log.Printf("using config %#v", m.config) - - if m.config.findBlobs { - m.verificationUtil, err = NewDataVerify( - m.ctx, - m.client.Database("data").Collection("deviceDataSets"), - ) - - if err != nil { - return fmt.Errorf("unable to create verification utils : %w", err) - } - return m.verificationUtil.WriteBlobIDs() - } - - if m.config.verifyDeduped { - m.verificationUtil, err = NewDataVerify( - m.ctx, - m.client.Database("data").Collection("deviceData"), - ) - - if err != nil { - return fmt.Errorf("unable to create verification utils : %w", err) - } - return m.verificationUtil.VerifyDeduped(m.config.uploadIdDeduped, strings.Split(m.config.dataTypes, ",")) - } - - if m.config.verifyDevice { - m.verificationUtil, err = NewDataVerify( - m.ctx, - m.client.Database("data").Collection("deviceData"), - ) - - if err != nil { - return fmt.Errorf("unable to create verification utils : %w", err) - } - return m.verificationUtil.VerifyDeviceUploads(m.config.userID, m.config.deviceID, strings.Split(m.config.dataTypes, ",")) - } - - m.verificationUtil, err = NewDataVerify( - m.ctx, - m.client.Database("data").Collection("deviceData"), - ) - - if err != nil { - return fmt.Errorf("unable to create verification utils : %w", err) - } - - err = m.verificationUtil.VerifyUploadDifferences(m.config.platformUploadID, m.config.jellyfishUploadID, strings.Split(m.config.dataTypes, ","), m.config.sameAccount) - if err != nil { - log.Printf("error running verify : %s", err.Error()) - } - return nil - } - - if err := m.CLI().Run(os.Args); err != nil { - if m.client != nil { - m.client.Disconnect(m.ctx) - } - log.Printf("error during Run [%s]", err.Error()) - os.Exit(1) - } -} - -func (m *Verify) Initialize() error { - m.CLI().Usage = "dataset verifictaion tool to compare dataset-a with dataset-b" - m.CLI().Authors = []cli.Author{ - { - Name: "J H BATE", - Email: "jamie@tidepool.org", - }, - } - m.CLI().Flags = append(m.CLI().Flags, - cli.StringFlag{ - Name: PlatformUploadIDFlag, - Usage: "uploadID of the first platform dataset", - Destination: &m.config.platformUploadID, - Required: false, - }, - cli.StringFlag{ - Name: JellyfishUploadIDFlag, - Usage: "uploadID of the second jellyfish dataset", - Destination: &m.config.jellyfishUploadID, - Required: false, - }, - cli.BoolFlag{ - Name: SameAccountFlag, - Usage: "the datasets are uploaded to the same account", - Destination: &m.config.sameAccount, - Required: false, - }, - cli.StringFlag{ - Name: UploadIDFlag, - Usage: "uploadID of the dataset to check deduping of", - Destination: &m.config.uploadIdDeduped, - Required: false, - }, - cli.StringFlag{ - Name: DeviceIDFlag, - Usage: "deviceID of the datasets to check", - Destination: &m.config.deviceID, - Required: false, - }, - cli.StringFlag{ - Name: UserIDFlag, - Usage: "userID of the device to check", - Destination: &m.config.userID, - Required: false, - }, - cli.StringFlag{ - Name: DataTypesFlag, - Usage: "comma seperated list of data types to compare", - Destination: &m.config.dataTypes, - Required: false, - Value: strings.Join(DatasetTypes, ","), - }, - cli.BoolFlag{ - Name: FindBlobFlag, - Usage: "find all blobs for running data verifcation with", - Destination: &m.config.findBlobs, - Required: false, - }, - cli.BoolFlag{ - Name: VerifyDedupedFlag, - Usage: "verify that a dataset has been deduplicated", - Destination: &m.config.verifyDeduped, - Required: false, - }, - cli.BoolFlag{ - Name: VerifyDeviceFlag, - Usage: "verify a device datasets", - Destination: &m.config.verifyDevice, - Required: false, - }, - cli.StringFlag{ - Name: MongoURIFlag, - Usage: "mongo connection URI", - Destination: &m.config.mongoURI, - Required: false, - //uri string comes from file called `uri` - FilePath: "./uri", - }, - ) - return nil -} - -func (m *Verify) CLI() *cli.App { - return m.cli -} From a0c8eb597bd12273ca95f9472749f71f9d8308a9 Mon Sep 17 00:00:00 2001 From: Darin Krauss Date: Tue, 10 Dec 2024 14:57:04 -0800 Subject: [PATCH 413/413] Fixes for device deactivate deduplicator (#793) --- data/deduplicator/deduplicator/base.go | 13 ++- data/deduplicator/deduplicator/base_test.go | 2 + .../data_set_delete_origin_test.go | 2 + .../deduplicator/device_deactivate_hash.go | 102 ++++++++---------- .../device_truncate_data_set_test.go | 2 + data/deduplicator/deduplicator/hash.go | 4 +- data/deduplicator/deduplicator/none_test.go | 2 + data/service/service/standard.go | 10 +- 8 files changed, 64 insertions(+), 73 deletions(-) diff --git a/data/deduplicator/deduplicator/base.go b/data/deduplicator/deduplicator/base.go index 19ad2ae6df..b6bf6dcc36 100644 --- a/data/deduplicator/deduplicator/base.go +++ b/data/deduplicator/deduplicator/base.go @@ -59,9 +59,16 @@ func (b *Base) Open(ctx context.Context, repository dataStore.DataRepository, da update := data.NewDataSetUpdate() update.Active = pointer.FromBool(dataSet.Active) - update.Deduplicator = data.NewDeduplicatorDescriptor() - update.Deduplicator.Name = pointer.FromString(b.name) - update.Deduplicator.Version = pointer.FromString(b.version) + update.Deduplicator = dataSet.Deduplicator + if update.Deduplicator == nil { + update.Deduplicator = data.NewDeduplicatorDescriptor() + } + if update.Deduplicator.Name == nil { + update.Deduplicator.Name = pointer.FromString(b.name) + } + if update.Deduplicator.Version == nil { + update.Deduplicator.Version = pointer.FromString(b.version) + } return repository.UpdateDataSet(ctx, *dataSet.UploadID, update) } diff --git a/data/deduplicator/deduplicator/base_test.go b/data/deduplicator/deduplicator/base_test.go index 94328ce37f..326495c3d5 100644 --- a/data/deduplicator/deduplicator/base_test.go +++ b/data/deduplicator/deduplicator/base_test.go @@ -65,6 +65,7 @@ var _ = Describe("Base", func() { Expect(err).ToNot(HaveOccurred()) Expect(deduplicator).ToNot(BeNil()) dataSet = dataTypesUploadTest.RandomUpload() + dataSet.Deduplicator = data.NewDeduplicatorDescriptor() dataSet.Deduplicator.Name = pointer.FromString(name) }) @@ -213,6 +214,7 @@ var _ = Describe("Base", func() { When("the data set has a deduplicator with matching name and version exists", func() { BeforeEach(func() { dataSet.Deduplicator.Version = pointer.FromString(netTest.RandomSemanticVersion()) + update.Deduplicator.Version = dataSet.Deduplicator.Version }) It("returns an error when update data set returns an error", func() { diff --git a/data/deduplicator/deduplicator/data_set_delete_origin_test.go b/data/deduplicator/deduplicator/data_set_delete_origin_test.go index 6691479632..0fff433201 100644 --- a/data/deduplicator/deduplicator/data_set_delete_origin_test.go +++ b/data/deduplicator/deduplicator/data_set_delete_origin_test.go @@ -41,6 +41,7 @@ var _ = Describe("DataSetDeleteOrigin", func() { Expect(err).ToNot(HaveOccurred()) Expect(deduplicator).ToNot(BeNil()) dataSet = dataTypesUploadTest.RandomUpload() + dataSet.Deduplicator = data.NewDeduplicatorDescriptor() dataSet.Deduplicator.Name = pointer.FromString("org.tidepool.deduplicator.dataset.delete.origin") }) @@ -199,6 +200,7 @@ var _ = Describe("DataSetDeleteOrigin", func() { When("the data set has a deduplicator with matching name and version exists", func() { BeforeEach(func() { dataSet.Deduplicator.Version = pointer.FromString(netTest.RandomSemanticVersion()) + update.Deduplicator.Version = dataSet.Deduplicator.Version }) It("returns an error when update data set returns an error", func() { diff --git a/data/deduplicator/deduplicator/device_deactivate_hash.go b/data/deduplicator/deduplicator/device_deactivate_hash.go index 9544ed677a..7d3f8d548c 100644 --- a/data/deduplicator/deduplicator/device_deactivate_hash.go +++ b/data/deduplicator/deduplicator/device_deactivate_hash.go @@ -25,7 +25,7 @@ var DeviceDeactivateHashDeviceManufacturerDeviceModels = map[string][]string{ "Trividia Health": {"TRUE METRIX", "TRUE METRIX AIR", "TRUE METRIX GO"}, } -var DeviceDeactivateLegacyHashManufacturerDeviceModels = map[string][]string{ +var DeviceDeactivateLegacyHashDeviceManufacturerDeviceModels = map[string][]string{ "Arkray": {"GlucocardExpression"}, "Bayer": {"Contour Next Link", "Contour Next Link 2.4", "Contour Next", "Contour USB", "Contour Next USB", "Contour Next One", "Contour", "Contour Next EZ", "Contour Plus", "Contour Plus Blue"}, "Dexcom": {"G5 touchscreen receiver", "G6 touchscreen receiver"}, @@ -42,17 +42,6 @@ type DeviceDeactivateHash struct { *Base } -func NewDeviceDeactivateLegacyHash() (*DeviceDeactivateHash, error) { - base, err := NewBase(DeviceDeactivateHashName, DeviceDeactivateHashVersionLegacy) - if err != nil { - return nil, err - } - - return &DeviceDeactivateHash{ - Base: base, - }, nil -} - func NewDeviceDeactivateHash() (*DeviceDeactivateHash, error) { base, err := NewBase(DeviceDeactivateHashName, DeviceDeactivateHashVersionCurrent) if err != nil { @@ -64,39 +53,30 @@ func NewDeviceDeactivateHash() (*DeviceDeactivateHash, error) { }, nil } -func getDeduplicatorVersion(dataSet *dataTypesUpload.Upload) (string, error) { - if dataSet.Deduplicator != nil { - if dataSet.Deduplicator.Name != nil && dataSet.Deduplicator.Version != nil { - if *dataSet.Deduplicator.Name == DeviceDeactivateHashName { - if *dataSet.Deduplicator.Version == DeviceDeactivateHashVersionLegacy { - return DeviceDeactivateHashVersionLegacy, nil - } else if *dataSet.Deduplicator.Version == DeviceDeactivateHashVersionCurrent { - return DeviceDeactivateHashVersionCurrent, nil - } - } - } +func getDeduplicatorVersion(dataSet *dataTypesUpload.Upload) (string, bool) { + if dataSet.DeviceManufacturers == nil || dataSet.DeviceModel == nil { + return "", false } - if dataSet.DeviceManufacturers != nil && dataSet.DeviceModel != nil { - for _, deviceManufacturer := range *dataSet.DeviceManufacturers { - if allowedDeviceModels, found := DeviceDeactivateLegacyHashManufacturerDeviceModels[deviceManufacturer]; found { - for _, allowedDeviceModel := range allowedDeviceModels { - if allowedDeviceModel == *dataSet.DeviceModel { - return DeviceDeactivateHashVersionLegacy, nil - } + + for _, deviceManufacturer := range *dataSet.DeviceManufacturers { + if allowedDeviceModels, found := DeviceDeactivateLegacyHashDeviceManufacturerDeviceModels[deviceManufacturer]; found { + for _, allowedDeviceModel := range allowedDeviceModels { + if allowedDeviceModel == *dataSet.DeviceModel { + return DeviceDeactivateHashVersionLegacy, true } } } - for _, deviceManufacturer := range *dataSet.DeviceManufacturers { - if allowedDeviceModels, found := DeviceDeactivateHashDeviceManufacturerDeviceModels[deviceManufacturer]; found { - for _, allowedDeviceModel := range allowedDeviceModels { - if allowedDeviceModel == *dataSet.DeviceModel { - return DeviceDeactivateHashVersionCurrent, nil - } + + if allowedDeviceModels, found := DeviceDeactivateHashDeviceManufacturerDeviceModels[deviceManufacturer]; found { + for _, allowedDeviceModel := range allowedDeviceModels { + if allowedDeviceModel == *dataSet.DeviceModel { + return DeviceDeactivateHashVersionCurrent, true } } } } - return "", errors.New("no valid device deactivate hash version") + + return "", false } func (d *DeviceDeactivateHash) New(ctx context.Context, dataSet *dataTypesUpload.Upload) (bool, error) { @@ -113,29 +93,39 @@ func (d *DeviceDeactivateHash) New(ctx context.Context, dataSet *dataTypesUpload return d.Get(ctx, dataSet) } - _, err := getDeduplicatorVersion(dataSet) - return err == nil, nil + _, found := getDeduplicatorVersion(dataSet) + return found, nil } func (d *DeviceDeactivateHash) Get(ctx context.Context, dataSet *dataTypesUpload.Upload) (bool, error) { - // NOTE: check legacy first then fallback to other matches - if dataSet == nil { - return false, errors.New("data set is missing") + if found, err := d.Base.Get(ctx, dataSet); err != nil || found { + return found, err } - version, err := getDeduplicatorVersion(dataSet) - if err != nil { - return false, err - } + return dataSet.HasDeduplicatorNameMatch("org.tidepool.hash-deactivate-old"), nil // TODO: DEPRECATED +} - if version == DeviceDeactivateHashVersionLegacy { - return true, nil +func (d *DeviceDeactivateHash) Open(ctx context.Context, repository dataStore.DataRepository, dataSet *dataTypesUpload.Upload) (*dataTypesUpload.Upload, error) { + if ctx == nil { + return nil, errors.New("context is missing") + } + if repository == nil { + return nil, errors.New("repository is missing") + } + if dataSet == nil { + return nil, errors.New("data set is missing") } - if found, err := d.Base.Get(ctx, dataSet); err != nil || found { - return found, err + version, found := getDeduplicatorVersion(dataSet) + if !found { + return nil, errors.New("deduplicator version not found") } - return dataSet.HasDeduplicatorNameMatch("org.tidepool.hash-deactivate-old"), nil // TODO: DEPRECATED + + dataSet.Deduplicator = data.NewDeduplicatorDescriptor() + dataSet.Deduplicator.Name = pointer.FromString(DeviceDeactivateHashName) + dataSet.Deduplicator.Version = pointer.FromString(version) + + return d.Base.Open(ctx, repository, dataSet) } func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore.DataRepository, dataSet *dataTypesUpload.Upload, dataSetData data.Data) error { @@ -153,13 +143,7 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore } options := NewDefaultDeviceDeactivateHashOptions() - - version, err := getDeduplicatorVersion(dataSet) - if err != nil { - return err - } - - if version == DeviceDeactivateHashVersionLegacy { + if *dataSet.Deduplicator.Version == DeviceDeactivateHashVersionLegacy { filter := &data.DataSetFilter{LegacyOnly: pointer.FromBool(true), DeviceID: dataSet.DeviceID} pagination := &page.Pagination{Page: 1, Size: 1} @@ -169,7 +153,7 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore } if len(uploads) != 0 { if uploads[0].LegacyGroupID == nil { - return errors.New("missing required legacy groupId for the device deactive hash legacy version") + return errors.New("missing required legacy groupId for the device deactivate hash legacy version") } options = NewLegacyHashOptions(*uploads[0].LegacyGroupID) } diff --git a/data/deduplicator/deduplicator/device_truncate_data_set_test.go b/data/deduplicator/deduplicator/device_truncate_data_set_test.go index e9bd9514be..a59797d7d1 100644 --- a/data/deduplicator/deduplicator/device_truncate_data_set_test.go +++ b/data/deduplicator/deduplicator/device_truncate_data_set_test.go @@ -41,6 +41,7 @@ var _ = Describe("DeviceTruncateDataSet", func() { Expect(deduplicator).ToNot(BeNil()) dataSet = dataTypesUploadTest.RandomUpload() dataSet.DataSetType = pointer.FromString("normal") + dataSet.Deduplicator = data.NewDeduplicatorDescriptor() dataSet.Deduplicator.Name = pointer.FromString("org.tidepool.deduplicator.device.truncate.dataset") dataSet.DeviceManufacturers = pointer.FromStringArray([]string{"Animas"}) }) @@ -248,6 +249,7 @@ var _ = Describe("DeviceTruncateDataSet", func() { When("the data set has a deduplicator with matching name and version exists", func() { BeforeEach(func() { dataSet.Deduplicator.Version = pointer.FromString(netTest.RandomSemanticVersion()) + update.Deduplicator.Version = dataSet.Deduplicator.Version }) It("returns an error when update data set returns an error", func() { diff --git a/data/deduplicator/deduplicator/hash.go b/data/deduplicator/deduplicator/hash.go index f38a557469..82c3780d9f 100644 --- a/data/deduplicator/deduplicator/hash.go +++ b/data/deduplicator/deduplicator/hash.go @@ -37,11 +37,11 @@ func (d HashOptions) Validate() error { switch d.Version { case types.LegacyIdentityFieldsVersion: if d.LegacyGroupID == nil || *d.LegacyGroupID == "" { - return errors.New("missing required legacy groupId for the device deactive hash legacy version") + return errors.New("missing required legacy groupId for the device deactivate hash legacy version") } case types.IdentityFieldsVersion: if d.LegacyGroupID != nil { - return errors.New("groupId is not required for the device deactive hash current version") + return errors.New("groupId is not required for the device deactivate hash current version") } default: return errors.Newf("missing valid version %d", d.Version) diff --git a/data/deduplicator/deduplicator/none_test.go b/data/deduplicator/deduplicator/none_test.go index 8c9f7a9808..b74590e18e 100644 --- a/data/deduplicator/deduplicator/none_test.go +++ b/data/deduplicator/deduplicator/none_test.go @@ -45,6 +45,7 @@ var _ = Describe("None", func() { Expect(err).ToNot(HaveOccurred()) Expect(deduplicator).ToNot(BeNil()) dataSet = dataTypesUploadTest.RandomUpload() + dataSet.Deduplicator = data.NewDeduplicatorDescriptor() dataSet.Deduplicator.Name = pointer.FromString("org.tidepool.deduplicator.none") }) @@ -203,6 +204,7 @@ var _ = Describe("None", func() { When("the data set has a deduplicator with matching name and version exists", func() { BeforeEach(func() { dataSet.Deduplicator.Version = pointer.FromString(netTest.RandomSemanticVersion()) + update.Deduplicator.Version = dataSet.Deduplicator.Version }) It("returns an error when update data set returns an error", func() { diff --git a/data/service/service/standard.go b/data/service/service/standard.go index aea30866d0..80911f4b20 100644 --- a/data/service/service/standard.go +++ b/data/service/service/standard.go @@ -207,13 +207,6 @@ func (s *Standard) initializeDataDeduplicatorFactory() error { return errors.Wrap(err, "unable to create device deactivate hash deduplicator") } - s.Logger().Debug("Creating device deactivate legacy hash deduplicator") - - deviceDeactivateLegacyHashDeduplicator, err := dataDeduplicatorDeduplicator.NewDeviceDeactivateLegacyHash() - if err != nil { - return errors.Wrap(err, "unable to create device deactivate legacy hash deduplicator") - } - s.Logger().Debug("Creating device truncate data set deduplicator") deviceTruncateDataSetDeduplicator, err := dataDeduplicatorDeduplicator.NewDeviceTruncateDataSet() @@ -238,11 +231,10 @@ func (s *Standard) initializeDataDeduplicatorFactory() error { s.Logger().Debug("Creating data deduplicator factory") deduplicators := []dataDeduplicatorFactory.Deduplicator{ - deviceDeactivateLegacyHashDeduplicator, + deviceDeactivateHashDeduplicator, deviceTruncateDataSetDeduplicator, dataSetDeleteOriginDeduplicator, noneDeduplicator, - deviceDeactivateHashDeduplicator, } factory, err := dataDeduplicatorFactory.New(deduplicators)